Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Mit C++ eine Verbindung zu einem MySQL-Server herstellen

Mit ein wenig Hilfe von Mat konnte ich herausfinden, was das Problem war, aber da er es nicht in Form einer Antwort gegeben hat, muss ich es beantworten, damit es für diejenigen geteilt werden kann, die es haben gleiches Problem, und auch als beantwortet markieren.

Mein Problem war also, dass ich keine Verbindung zur Datenbank herstellen konnte. Wie Mat vorgeschlagen hat, sollte ich die erweiterten Fehlerinformationen verwenden, die als SQLGetDiagRec bekannt sind und beheben Sie auch die Argumente gemäß der Dokumentation. Ich brauchte einen Moment, um zu lernen, wie die SQLGetDiagRec Funktion funktioniert, aber sobald ich es geschafft habe, den wchar_t zu konvertieren zu char * Ich konnte den Fehler sehen, den es generierte.

Der Verbindungsversuch gab mir den Fehler Data source not found and no default driver specified . Das gab mir einen Hinweis darauf, dass ich entweder die falsche Verbindungszeichenfolge geschrieben habe oder dass die Textzeichenfolge irgendwie falsch interpretiert oder verstümmelt wurde.

Etwas im Netz suchen gab mir die Einsicht, dass der String falsch interpretiert wurde, und um ihn zu beheben, musste ich ihn zu einem wörtlichen String machen. Sicher genug, das Setzen eines L vor der Zeichenfolge hat es gelöst!

retcode = SQLDriverConnect(hdbc, 0, 
                           (SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;", 
                           _countof(L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;"), 
                           OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_COMPLETE);

Gleichzeitig lernte ich, wie man die Eingabeaufforderung loswird, was nach der Behebung des anfänglichen Problems recht einfach herauszufinden war. Geben Sie null für das Fensterhandle an und setzen Sie die Treibervervollständigung auf SQL_DRIVER_COMPLETE und stellen Sie sicher, dass Sie alle erforderlichen Informationen in der Verbindungszeichenfolge hinzufügen.

Das nächste Problem hatte ich also bei der Abfrage mit SQLExecDirect gab einen Fehler aus, der besagte:Syntax error or access violation . Das Problem war offensichtlich dasselbe wie bei der Verbindungszeichenfolge. Sicher genug

retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);

Hat wunderbar funktioniert.

Hier ist der vollständige Code, voll funktionsfähig:

#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>

using namespace std;

int main(){
    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;
    SQLRETURN retcode;

    SQLWCHAR OutConnStr[255];
    SQLSMALLINT OutConnStrLen;

    // Allocate environment handle
    retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

    // Set the ODBC version environment attribute
    if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
        retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 

        // Allocate connection handle
        if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
            retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 

             // Set login timeout to 5 seconds
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);

                // Connect to data source
                retcode = SQLDriverConnect(
                    hdbc, 
                    0,
                    (SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;", 
                    _countof(L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;"),
                    OutConnStr,
                    255, 
                    &OutConnStrLen,
                    SQL_DRIVER_COMPLETE );

                // Allocate statement handle
                if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                    retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

                    // Process data
                    retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);

                    if (retcode == SQL_SUCCESS) {
                        SQLINTEGER sTestInt, cbTestStr, cbTestInt, cbTestFloat, iCount = 1;
                        SQLFLOAT dTestFloat;
                        SQLCHAR szTestStr[200];
                        while (TRUE) {
                            retcode = SQLFetch(hstmt);
                            if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
                                cout<<"An error occurred";
                            }
                            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){

                                SQLGetData(hstmt, 1, SQL_C_CHAR, szTestStr, 200, &cbTestStr);
                                SQLGetData(hstmt, 2, SQL_C_ULONG, &sTestInt, 0, &cbTestInt);
                                SQLGetData(hstmt, 3, SQL_C_DOUBLE, &dTestFloat, 0,&cbTestFloat);

                                /* Print the row of data */
                                cout<<"Row "<<iCount<<":"<<endl;
                                cout<<szTestStr<<endl;
                                cout<<sTestInt<<endl;
                                cout<<dTestFloat<<endl;
                                iCount++;
                            } else {
                                break;
                            }
                        }
                    }else{
                        cout<<"Query execution error."<<endl;
                    }

                    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
                    SQLDisconnect(hdbc);
                }else{ 
                    cout<<"Connection error"<<endl;
                }
                SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
            }
        }
        SQLFreeHandle(SQL_HANDLE_ENV, henv);
    }

        system("pause");
    return 0;
}

Es zeigt sich nur, dass selbst die kleinste Sache alles zum Scheitern bringen kann.

Danke Mat für deine Hilfe.