sql >> Databasteknik >  >> RDS >> Mysql

Ansluter till en MySQL-server med C++

Med lite hjälp av Mat kunde jag komma på vad problemet var, men eftersom han inte gav det i form av ett svar så får jag svara på det så att det kan delas för de som har samma problem, och även markera som besvarat.

Så mitt problem var att jag inte kunde ansluta till databasen. Som Mat föreslog borde jag använda den utökade felinformationen, känd som SQLGetDiagRec och fixa även argumenten enligt dokumentationen. Det tog mig en stund att lära mig hur SQLGetDiagRec funktionen fungerar, men när jag lyckades konvertera wchar_t till char * Jag kunde se felet det genererade.

Anslutningsförsöket gav mig felet Data source not found and no default driver specified . Det gav mig en ledtråd, vilket tydde på att jag antingen skrev den felaktiga anslutningssträngen eller att textsträngen på något sätt var feltolkad eller förvanskad.

Gör lite sökning på nätet gav mig insikten att strängen var feltolkad, och för att fixa den var jag tvungen att göra den till en bokstavlig sträng. Visst löste det sig att sätta ett L framför snöret!

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

Samtidigt lärde jag mig att bli av med prompten, vilket var ganska lätt att ta reda på efter att ha åtgärdat det initiala problemet. Ange null för fönsterhandtaget, ställ in drivrutinskomplettering till SQL_DRIVER_COMPLETE och se till att du lägger till all information som behövs i anslutningssträngen.

Så nästa problem jag hade med frågan med SQLExecDirect gav ett felmeddelande som säger Syntax error or access violation . Problemet var uppenbarligen detsamma som med anslutningssträngen. Säkert nog

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

Fungerade som en smäck.

Här är koden i sin helhet, fullt fungerande:

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

Det visar sig bara att även den minsta sak kan få allt att misslyckas.

Tack Mat för din hjälp.



  1. Unicode (grekiska) tecken lagras i databasen som ??????

  2. BILAGA sqlite-databas i Android med SQLiteOpenHelper

  3. mysql välj datum inom 30-dagarsintervallet

  4. JDBC PreparedStatement resulterar i MySQL-syntaxfel