Mysql
 sql >> Database >  >> RDS >> Mysql

Connessione a un server MySQL tramite C++

Con un piccolo aiuto di Mat, sono riuscito a capire quale fosse il problema, ma siccome lui non lo ha dato in forma di risposta, dovrò rispondere in modo che possa essere condiviso per coloro che hanno il stesso problema, e anche da contrassegnare come risposta.

Quindi, il mio problema era che non riuscivo a connettermi al database. Come suggerito da Mat, dovrei usare le informazioni di errore estese, note come SQLGetDiagRec e anche correggere gli argomenti in base alla documentazione. Mi ci è voluto un momento per imparare a usare SQLGetDiagRec funziona, ma una volta sono riuscito a convertire il wchar_t a char * Sono riuscito a vedere l'errore che stava generando.

Il tentativo di connessione mi ha dato l'errore Data source not found and no default driver specified . Questo mi ha dato un indizio, indicando che ho scritto la stringa di connessione errata o che la stringa di testo è stata in qualche modo interpretata erroneamente o alterata.

Facendo alcune cerche in rete mi ha dato l'idea che la stringa è stata interpretata erroneamente e per risolverla ho dovuto renderla una stringa letterale. Sicuramente, mettere una L davanti alla stringa ha risolto!

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);

Allo stesso tempo, ho imparato come sbarazzarmi del prompt, che era abbastanza facile da capire dopo aver corretto il problema iniziale. Specificare null per l'handle della finestra, impostare il completamento del driver su SQL_DRIVER_COMPLETE e assicurati di aggiungere tutte le informazioni necessarie nella stringa di connessione.

Quindi, il prossimo problema che ho avuto con la query con SQLExecDirect stava dando un errore dicendo Syntax error or access violation . Il problema era ovviamente lo stesso della stringa di connessione. Sicuramente abbastanza

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

Ha funzionato come un incantesimo.

Ecco il codice nella sua interezza, perfettamente funzionante:

#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;
}

Questo è solo per dimostrare che anche la cosa più piccola può far fallire tutto.

Grazie Mat per il tuo aiuto.