MySQL und Borland



  • Hallo ich habe folgendes Problem.

    Ich habe mir eine Klasse geschrieben mit der ich auf eine MySQL Datenbank zugreifen möchte. Ich greife über die libmysql.dll auf die Funktionen zu.

    Leider klappt der Teil ab mysql_fecth_row überhaupt nicht. dieser Teil bring meine Programm dauernd zu Absturz. Was mache ich falsch?

    Danke für eure Hilfe

    Anbei der Code meines Programms:

    // main.cpp
    
    #ifdef __BORLANDC__
    	#pragma argsused
    #endif
    #include <stdio.h>
    #include "MDBConnector.h"
    int main(int argc, char* argv[])
    {
    	MDBConnector* mDBConnector = new MDBConnector();
    	mDBConnector->SetDatabaseName("ausgaben");
    	mDBConnector->SetUser("mike");
    	mDBConnector->SetPassword("");
    	mDBConnector->SetHost("localhost");
    	mDBConnector->SetPort(3306);
    	mDBConnector->Connect();
    
    	if (mDBConnector->Execute("Select * from costs_t"))
    	{
    	  printf("true");
    	}
    	system("PAUSE");
    	delete mDBConnector;
    	return 0;
    }
    
    // MDBConnector.h
    #ifndef MDBCONNECTOR_H_
    #define MDBCONNECTOR_H_
    
    #include <stdlib.h>
    #include "MySQLDefs.h"
    
    class MDBConnector
    {
    	public:
    		MDBConnector(void);
    		~MDBConnector(void);
    
    		void SetDatabaseName(std::string);
    		void SetUser(std::string);
    		void SetPassword(std::string);
    		void SetHost(std::string);
    		void SetPort(unsigned int);
    
    		void Connect(void);
    		void Close(void);
    		bool Execute(std::string);
    
    		unsigned int GetRowCount();
    		unsigned int GetColCount();
    	protected:
    		void LoadFunctions();
    		std::string mDatabaseName;
    		std::string mUser;
    		std::string mPassword;
    		std::string mHost;
    
    		MYSQL* mDatabaseHandle;
    
    		unsigned int mPort;
    		unsigned int mRows;
    		unsigned int mCols;
    
    		HINSTANCE mDll;
    };
    
    #endif //MDBCONNECTOR_H_
    
    // MDBConnector.cpp
    #include "MDBConnector.h"
    #include <stdio.h>
    MySQL_Init sql_init = NULL;
    MySQL_Real_Connect sql_connect = NULL;
    MySQL_Close sql_close = NULL;
    MySQL_Query sql_query = NULL;
    MySQL_Store_Result sql_store_result = NULL;
    MySQL_Num_Fields sql_num_fields = NULL;
    MySQL_Num_Rows sql_num_rows = NULL;
    MySQL_Fetch_Fields sql_fetch_fields = NULL;
    MySQL_Fetch_Row sql_fetch_row = NULL;
    MySQL_Free_Result sql_free_result = NULL;
    //==============================================================================
    MDBConnector::MDBConnector()
    	:	mDatabaseHandle(NULL),
    		mDll(NULL),
    		mRows(0),
    		mCols(0)
    {
    	mDll = LoadLibrary("libmysql.dll");
    	LoadFunctions();
    }
    //==============================================================================
    MDBConnector::~MDBConnector()
    {
    	if (mDatabaseHandle)
    	{
    		Close();
    	}
    	FreeLibrary(mDll);
    }
    //==============================================================================
    void MDBConnector::SetDatabaseName(std::string name)
    {
    	mDatabaseName = name;
    }
    //==============================================================================
    void MDBConnector::SetUser(std::string user)
    {
    	mUser = user;
    }
    //==============================================================================
    void MDBConnector::SetPassword(std::string password)
    {
    	mPassword = password;
    }
    //==============================================================================
    void MDBConnector::SetHost(std::string host)
    {
    	mHost = host;
    }
    //==============================================================================
    void MDBConnector::SetPort(unsigned int port)
    {
    	mPort = port;
    }
    //==============================================================================
    void MDBConnector::Connect()
    {
    	if (mDll)
    	{
    		if (sql_init)
    		{
    			mDatabaseHandle = sql_init(NULL);
    			if (mDatabaseHandle)
    			{
    				if (sql_connect)
    				{
    					MYSQL* result = sql_connect(
    											mDatabaseHandle, "localhost", "mike", "",
    											"ausgaben", 3306, NULL, 0
    										);
    					if (!result)
    					{
    						Close();
    						//Fehlerbehandlung
    					}
    				}
    				else
    				{
    					//Fehlerbehandlung
    				}
    			}
    			else
    			{
    				//Fehlerbehandlung
    			}
    		}
    		else
    		{
    			//Fehlerbehandlung
    		}
    	}
    	else
    	{
    		//Fehlerbehandlung
    	}
    
    }
    //==============================================================================
    void MDBConnector::Close()
    {
    	if (mDll)
    	{
    		if (mDatabaseHandle)
    		{
    			if (mDatabaseHandle)
    			{
    				if (sql_close)
    				{
    					sql_close(mDatabaseHandle);
    				}
    				else
    				{
    					//Fehlerbehandlung
    				}
    			}
    		}
    	}
    	else
    	{
    		//Fehlerbehandlung
    	}
    
    }
    //==============================================================================
    bool MDBConnector::Execute(std::string statement)
    {
    	int result = -1;
    	if ((mDll) && (mDatabaseHandle))
    	{
    		if (sql_query)
    		{
    			if (sql_query(mDatabaseHandle, "Select * from costs_t") == 0)
    			{
    				if ((sql_store_result) && (sql_free_result))
    				{
    					MYSQL_RES* res = sql_store_result(mDatabaseHandle);
    					if (sql_num_fields)
    					{
    						mCols = sql_num_fields(res);
    					}
    					if (sql_num_rows)
    					{
    						mRows = sql_num_rows(res);
    					}
    					if (sql_fetch_row)
    					{
    						MYSQL_ROW row;
    						while((row = sql_fetch_row(res)))
    						{
    							for (int c = 0; c < mCols; c++)
    							{
    								printf("[%.*s] ", row[c] ? row[c] : "NULL");
    							}
    						}
    					}
    					sql_free_result(res);
    				}
    				return true;
    			}
    		}
    		else
    		{
    			//Fehlerbehandlung
    		}
    	}
    	return false;
    }
    //==============================================================================
    unsigned int MDBConnector::GetRowCount()
    {
    	return mRows;
    }
    //==============================================================================
    unsigned int MDBConnector::GetColCount()
    {
    	return mCols;
    }
    //==============================================================================
    void MDBConnector::LoadFunctions()
    {
    	if (mDll)
    	{
    		sql_init = (MySQL_Init)GetProcAddress(mDll, "mysql_init");
    		sql_connect = (MySQL_Real_Connect)GetProcAddress(mDll, "mysql_real_connect");
    		sql_close = (MySQL_Close)GetProcAddress(mDll, "mysql_close");
    		sql_query = (MySQL_Query)GetProcAddress(mDll, "mysql_query");
    		sql_store_result = (MySQL_Store_Result)GetProcAddress(mDll, "mysql_store_result");
    		sql_num_fields =	(MySQL_Num_Fields)GetProcAddress(mDll, "mysql_num_fields");
    		sql_num_rows =	(MySQL_Num_Rows)GetProcAddress(mDll, "mysql_num_rows");
    		sql_fetch_fields = (MySQL_Fetch_Fields)GetProcAddress(mDll, "mysql_fetch_fields");
    		sql_fetch_row = (MySQL_Fetch_Row)GetProcAddress(mDll, "mysql_fetch_row");
    		sql_free_result = (MySQL_Free_Result)GetProcAddress(mDll, "mysql_free_result");
    	}
    }
    //==============================================================================
    


  • ZuBesuch schrieb:

    Leider klappt der Teil ab mysql_fecth_row überhaupt nicht. dieser Teil bring meine Programm dauernd zu Absturz. Was mache ich falsch?

    Denke mal du hast hier nen tipfehler gemacht: mysql_fecth_row (im quellcode mysql_fetch_row). 😉

    Ne frage, wenn du mysql_fetch_row das erste mal benutzt, stürzt das Programm auch ab?
    Oder stürzt das Programm beim 2x benutzen von mysql_fetch_row ab?



  • DJ BlackEagle schrieb:

    ZuBesuch schrieb:

    Leider klappt der Teil ab mysql_fecth_row überhaupt nicht. dieser Teil bring meine Programm dauernd zu Absturz. Was mache ich falsch?

    Denke mal du hast hier nen tipfehler gemacht: mysql_fecth_row (im quellcode mysql_fetch_row). 😉

    Ne frage, wenn du mysql_fetch_row das erste mal benutzt, stürzt das Programm auch ab?
    Oder stürzt das Programm beim 2x benutzen von mysql_fetch_row ab?

    Wenn ich debugge klappt es meistens das erste mal... danach nicht.
    Ich habe diesen teil

    while((row = sql_fetch_row(res)))
    {
         for (int c = 0; c < mCols; c++)
         {
            printf("[%.*s] ", row[c] ? row[c] : "NULL");
         }
    }
    

    auch mal mit einer for-Schleife versucht und zwar folgendermaßen:

    for (int r = 0; r < mRows; r++)
    {
         row = sql_fetch_row(res);
         for (int c = 0; c < mCols; c++)
         {
            printf("[%.*s] ", row[c] ? row[c] : "NULL");
         }
    }
    

    Seltsamerweise wurde r beim ersten durchlauf dann automatisch ein eine zufallszahl gesetzt z.B.: 43465



  • ZuBesuch schrieb:

    for (int r = 0; r < mRows; r++)
    {
         row = sql_fetch_row(res);
         for (int c = 0; c < mCols; c++)
         {
            printf("[%.*s] ", row[c] ? row[c] : "NULL");
         }
    }
    

    Seltsamerweise wurde r beim ersten durchlauf dann automatisch ein eine zufallszahl gesetzt z.B.: 43465

    Mit der Zahl müßte nach for(xxx) r = 0 sein (Sprich in der Zeile row = sql_fetch_row(res); ).

    ZuBesuch schrieb:

    if (sql_num_rows) <-- macht mir sorgen
    {
    mRows = sql_num_rows(res);
    }
    if (sql_fetch_row) <-- das ebenfalls
    {
    }

    Warum machen die 2 Dinge Sorgen?
    Wenn ich deine Methode Execute einmal aufrufe und dann nochmal aufrufe die Methode, dann kann der alte Wert drin stehen. Dann kann es zu ein Fehler kommen, wenn der Inhalt ungültig (alt) ist.

    Und du solltest auch mal prüfen ob res ein gültigen Wert hat, wenn der Wert = NULL ist sollte du die while/for überspringen.

    Tip du solltest das Init teil so machen:

    MYSQL* pMySQL = mysql_init(NULL);
    

    Bricht der Debugger in der Zeile ab:

    while((row = sql_fetch_row(res)))
    

    oder woanders? Wenn woanders, dann wo genau...



  • DJ BlackEagle schrieb:

    Bricht der Debugger in der Zeile ab:

    while((row = sql_fetch_row(res)))
    

    oder woanders? Wenn woanders, dann wo genau...

    Also der Fehler tritt auf wenn ich den inhalt von row[c] etwas zuweisen will.

    z.B.

    printf("[%.*s] ", row[c] ? row[c] : "NULL");
    

    oder

    std::string str = row[c];
    

    oder

    char str[256];
    strcpy(str, row[c]);
    

    Wenn ich aber folgendes mache:

    printf("%s\n", row[c]);
    

    klappt alles wie geschmiert.

    Ich habe keine Ahnung warum.



  • printf("[%.*s] ", row[c] ? row[c] : "NULL");
    

    ok. da weißt du auch nix zu.
    naja was du da machst ist auch falsch wie ich sehe. weil so geht eien if-short-conditional nicht.

    so:

    printf("[%s] ", (row[c]) ? row[c] : "NULL");
    

    entsprechend anpassen.
    ich frag mich nur was "%.*s" zu bedeutet.



  • DJ BlackEagle schrieb:

    printf("[%.*s] ", row[c] ? row[c] : "NULL");
    

    ok. da weißt du auch nix zu.
    ich frag mich nur was "%.*s" zu bedeutet.

    Hi Sorry,

    ich habe mich vertippt. Richtig muss es heißen:

    if (sql_fetch_row)
    {
       MYSQL_ROW row;
       while((row = sql_fetch_row(res)))
       {
          unsigned long *laengen;
          laengen = sql_fetch lengths(res);
          for (int c = 0; c < mCols; c++)
          {
             printf("[%.*s] ", laengen[i], row[c] ? row[c] : "NULL");
          }
       }
    }
    

    sql_fetch_lengths is ein typedef für mysql_fetch_lengths.

    So klappt das dann auch, nur kann ich den Wert immernoch nicht einem std::string zuweisen.



  • Das
    [cpp]
    if (sql_fetch_row)
    {
    MYSQL_ROW row;
    while((row = sql_fetch_row(res)))
    {
    unsigned long *laengen;
    laengen = sql_fetch lengths(res);
    for (int c = 0; c < mCols; c++)
    {
    printf("[%.*s] ", laengen[i], row[c] ? row[c] : "NULL");
    }
    }
    }
    [/cpp]

    zu

    if (sql_fetch_row)
    {
       MYSQL_ROW row;
       while((row = sql_fetch_row(res)))
       {
          unsigned long *laengen;
          laengen = sql_fetch lengths(res);
          for (int c = 0; c < mCols; c++)
          {
             printf("[%.*s] ", laengen[i], (row[c]) ? row[c] : "NULL");
          }
       }
    }
    

    Weil

    (row[c]) ? row[c] : "NULL";
    

    ist ein if-short-conditional.

    Das würde so aussehen:

    peter = (row[c]) ? row[c] : "NULL";
    

Anmelden zum Antworten