こんにちはすべて、ODBC -
は、ODBC SQLドライバーとデータソースのものを開発する方法を学んでコツコツ、私は思わぬ障害のビットに実行しているように見えるC++でプリペアドステートメントをコーディング。私は現在、次のステートメントを使用して、データベース上のプリペアドステートメントで働いている:
英語でselect * from TEST1 where NAME = ? and LOCATION__LATITUDE__S = ?
は、名前と緯度座標指定する-でTEST1からすべてのレコードを検索します。 ODBCTestアプリケーションで上記を行うことができるので、データソースに接続してパラメータ化されたクエリを使用してクエリを実行できます。ここでは、私は私の問題の関数のコードを持っているものです:13個の属性(3行、13列)の3つの記録:
void ExecPreparedStatement(const char* stmt) {
HSTMT hstmt;
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
RETCODE rc = SQLPrepare(hstmt, (WCHAR*)stmt, SQL_NTS);
SQLSMALLINT numParams;
rc = SQLNumParams(hstmt, &numParams);
WCHAR* param1 = (WCHAR*)L"Jacob";
SQLFLOAT param2 = 40.0;
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, (SQLPOINTER)param1, 300, NULL);
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, ¶m2, 300, NULL);
rc = SQLExecute(hstmt); /* <fails here> */
SQLSMALLINT numCols;
SQLNumResultCols(hstmt, &numCols);
DisplayRecords(hstmt, numCols);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
このは私のテストアプリケーションから同じ結果を与える必要があります。代わりに、実行に失敗します。読書を容易にするために、私はRetCodeのすべての処理をコードから削除しましたが、ステートメントが完了したことをチェックし、失敗した場合は正常に処理することができます。ここで私が誤解しているものがなければなりません。また、文からのパラメータの数が0(numParams変数)であることもわかります。私はこれがExecuteコールの後に置かれるべきだと理論化していますが、私はその時点まで実行されることはないので、今すぐテストすることはできません。
アイデア?ここのレンガの壁に私の頭をぶつける。 MSDNおよびその他のオンラインソースは、この点について有益ではありません。
主な質問の明確化:誰かがなぜ実行機能が失敗しているのか分かりませんか?
ANSWERは
問題が誤用鋳造による不正なSQLがわかりました。関数にconst char *文字列を渡すのではなく、代わりにWCHAR *でキャストされた文字列を渡し、関数の中でWCHAR *を使用します。機能コードは次のようになります。TryODBC()
HSTMT hstmt;
SQLAllocStmt(hdbc, &hstmt);
TryODBC(hstmt, SQL_HANDLE_STMT, SQLPrepare(hstmt, stmt, SQL_NTS));
// Prepare passes test - we return 0.
WCHAR* param1 = (WCHAR*)L"Jacob";
TryODBC(hstmt, SQL_HANDLE_STMT,
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR,
SQL_WVARCHAR, 80, 0, (SQLPOINTER)param1, 300, NULL)
);
TryODBC(hstmt, SQL_HANDLE_STMT, SQLExecute(hstmt));
SQLSMALLINT numCols;
TryODBC(hstmt, SQL_HANDLE_STMT, SQLNumResultCols(hstmt, &numCols));
DisplayRecords(hstmt, numCols);
SQLFreeStmt(hstmt, SQL_CLOSE);
次のように関数である。SQLGetDiagRecの()関数の方に私を導くための@ergする
bool disconnectOnError = false;
if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_ERROR) {
if (!Success(rc)) {
disconnectOnError = true;
}
SQLWCHAR state[6], errorMsg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER nativeError;
SQLSMALLINT i = 1, msgLen;
while ((rc = SQLGetDiagRec(handleType, handle, i, state,
&nativeError, errorMsg, sizeof(errorMsg), &msgLen)) != SQL_NO_DATA)
{
ShowMessage(nativeError, errorMsg);
i++;
}
}
if (disconnectOnError) {
Disconnect(-1);
}
大規模な感謝。
失敗した行にはどのようなエラーがありますか? 'SQLGetDiagRec'はあなたに良いヒントを与えるはずです。それ以上の場合は、https:// stackoverflowを提供してください。com/help/mcve – erg
@ergこれは、感謝しました!私はSQLGetDiagRecとその使用法を知らなかったので、グーグルと実験を少し行いました。問題は、SQLがキャストの悪用とSQLWCHARの悪用によって何らかの形で不正行為を起こしていたことです。 –