SQL Server への ODBC 接続を開き、クエリを発行し、結果を出力する C++ の小さなサンプル プログラムをダウンロードしました。
クエリ文字列にパラメーターが含まれていて、SQLBindParameter を呼び出すと、クエリの実行で SQL_SUCCESS が返されますが、その後、レコードの取得に失敗します。
SQL Management studio で同等のクエリを直接実行すると、機能します。
これがコードです。簡潔にするために、問題が発生していない場所のエラー チェックを削除したことに注意してください。実際の接続文字列は難読化されています。
SQLHANDLE sqlenvhandle = 0;
SQLHANDLE sqlconnectionhandle = 0;
SQLHANDLE sqlstatementhandle = 0;
SQLHANDLE sqlstatementhandle2 = 0;
SQLRETURN retcode = 0;
SQLWCHAR retconstring[1024];
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlenvhandle);
retcode = SQLSetEnvAttr(sqlenvhandle,SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
retcode = SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle);
retcode = SQLDriverConnect(sqlconnectionhandle, NULL, (SQLWCHAR*)_T("--connectionstring--"),
SQL_NTS, retconstring, 1024, NULL, SQL_DRIVER_NOPROMPT);
retcode = SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle2);
SQLWCHAR *query = _T("SELECT * FROM gbm_models WHERE stagename like ?");
SQLWCHAR *searchname = _T("Yuk%\0");
retcode = SQLPrepare (sqlstatementhandle2, query, SQL_NTS);
SQLINTEGER xxx = SQL_NTS;
retcode = SQLBindParameter( sqlstatementhandle2, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_VARCHAR, 5, 0, searchname, 0, &xxx );
SQLWCHAR sqlbuffer[400];
SQLINTEGER buflen = 0;
retcode = SQLExecute (sqlstatementhandle2);
char name[512];
int id;
while(SQLFetch(sqlstatementhandle2) == SQL_SUCCESS)
{
SQLGetData(sqlstatementhandle2, 1, SQL_C_ULONG, &id, 0, NULL);
SQLGetData(sqlstatementhandle2, 4, SQL_C_CHAR, name, 500, NULL);
cout << id << " " << name << endl;
}
SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle2 );
SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle );
SQLDisconnect(sqlconnectionhandle);
SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
SQLFreeHandle(SQL_HANDLE_ENV, sqlenvhandle);
これらの呼び出しはいずれもエラーを返しません。SQLFetchを呼び出すと、SQL_NO_DATA が返されます。「?」を置き換えると 最初のクエリ文字列で実際の名前文字列を使用し、SQLBindParameter呼び出しをコメント アウトすると、正常に動作し、期待されるデータが取得されます。したがって、明らかに、検索文字列はクエリに正しく組み込まれていません。
何が問題なのですか?パラメータ置換を行って処理されたクエリ文字列を取得する方法を知っている人はいますか? SQLNativeSql関数がそれを行っていると思っていましたが、呼び出すと元のクエリが返されるだけなので、正しく機能しているかどうかはわかりません。それはUnicodeのことでしょうか?