sql >> データベース >  >> RDS >> Mysql

C++を使用してMySQLサーバーに接続する

    マットの助けを借りて、何が問題なのかを理解することができましたが、彼は答えの形でそれを与えなかったので、それを持っている人と共有できるように答える必要があります同じ問題であり、回答済みとしてマークすることもできます。

    それで、私の問題は、データベースに接続できないことでした。 Matが提案したように、SQLGetDiagRecとして知られる拡張エラー情報を使用する必要があります。 また、ドキュメントに従って引数を修正します。 SQLGetDiagRecの方法を学ぶのに少し時間がかかりました 関数は機能しますが、wchar_tを変換できたら char *へ 生成されたエラーを確認できました。

    接続しようとすると、Data source not found and no default driver specifiedというエラーが表示されました。 。それは私に手がかりを与え、私が間違った接続文字列を書いたか、テキスト文字列が何らかの形で誤って解釈されたか、壊れていることを示しています。

    ネットで検索 を実行する 文字列が誤って解釈されているという洞察を私に与えました、そしてそれを修正するために私はそれをリテラル文字列にしなければなりませんでした。確かに、文字列の前にLを付けると、問題は解決しました。

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

    同時に、最初の問題を修正した後、非常に簡単に理解できるプロンプトを取り除く方法を学びました。ウィンドウハンドルにnullを指定し、ドライバーの完了をSQL_DRIVER_COMPLETEに設定します 接続文字列に必要なすべての情報を必ず追加してください。

    したがって、SQLExecDirectを使用したクエリで発生した次の問題 Syntax error or access violationというエラーが表示されていました 。問題は明らかに接続文字列の場合と同じでした。確かに

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

    チャームのように機能しました。

    完全に機能するコード全体は次のとおりです。

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

    見に行くだけで、どんなに小さなことでもすべてが失敗する可能性があります。

    マットさん、ありがとうございました。



    1. MySQLトリガーはCHECK制約をシミュレートできますか?

    2. MySQLの日付形式

    3. 日時ではなく日時を扱う

    4. SQLServerの行オフセット