私は、ほとんどの操作の後に影響を受ける行を健全性チェックする顧客の ODBC アプリケーションを持っています。突然、これらのチェックが失敗します。この場合、挿入後、影響を受ける行は 1 であると予想されます。ログを確認した後、その値は不明 (-1) に戻ります。
なぜ動作が変わるのか、誰にも分かりますか?
追加情報:
- アプリケーションが Windows サーバーで実行されている
- データベースはオラクルです。
- ドライバーは Microsoft Oracle Driver です。
- 顧客は、データベースまたはドライバーへのアップグレードが最近行われていないと述べています。
- 顧客は、テーブル内のいくつかの行を変更または削除した後に問題が発生したと主張しています。
追加の詳細:
ドライバーは「Microsoft ODBC for Oracle」、バージョンは 2.576.3959.00、ファイル名は MSORCL32.dll、日付は 2007 年 2 月 17 日です。Oracle データベースのレベルは 10.2 です。
何か案は?
以下は、彼らにキャプチャしてもらった ODBC ログです。
dpxag35 a5c-cac ENTER SQLExecDirect HSTMT 015A2270 UCHAR * 0x00177D9C [ 364] "begin \ a <single simple insert statement here>; \ aend;" SDWORD 364 dpxag35 a5c-cac EXIT SQLExecDirect with return code 0 (SQL_SUCCESS) HSTMT 015A2270 UCHAR * 0x00177D9C [ 364] "begin \ a <single simple insert statement here>; \ aend;" SDWORD 364 dpxag35 a5c-cac ENTER SQLNumResultCols HSTMT 015A2270 SWORD * 0x0012F9B0 dpxag35 a5c-cac EXIT SQLNumResultCols with return code 0 (SQL_SUCCESS) HSTMT 015A2270 SWORD * 0x0012F9B0 (0) dpxag35 a5c-cac ENTER SQLRowCount HSTMT 015A2270 SQLLEN * 0x00163B88 dpxag35 a5c-cac EXIT SQLRowCount with return code 0 (SQL_SUCCESS) HSTMT 015A2270 SQLLEN * 0x00163B88 (-1) dpxag35 a5c-cac ENTER SQLFreeStmt HSTMT 015A2270 UWORD 0 <SQL_CLOSE> dpxag35 a5c-cac EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS) HSTMT 015A2270 UWORD 0 <SQL_CLOSE>
参考までに、これは MSDN の ODBC ドキュメントからのものです。
RowCountPtr[出力] 行数を返すバッファーを指します。UPDATE、INSERT、および DELETE ステートメントの場合、SQLBulkOperations の SQL_ADD、SQL_UPDATE_BY_BOOKMARK、および SQL_DELETE_BY_BOOKMARK 操作の場合、および SQLSetPos の SQL_UPDATE または SQL_DELETE 操作の場合、*RowCountPtr に返される値は、要求によって影響を受ける行の数または -1 です。影響を受ける行の数が利用できない場合。SQLExecute、SQLExecDirect、SQLBulkOperations、SQLSetPos、または SQLMoreResults が呼び出されると、診断データ構造の SQL_DIAG_ROW_COUNT フィールドが行数に設定され、行数は実装に依存する方法でキャッシュされます。SQLRowCount は、キャッシュされた行数の値を返します。キャッシュされた行数の値は、ステートメント ハンドルが準備済みまたは割り当て済みの状態に戻されるまで有効です。ステートメントが再実行されるか、SQLCloseCursor が呼び出されます。SQL_DIAG_ROW_COUNT フィールドが設定された後に関数が呼び出された場合、SQL_DIAG_ROW_COUNT フィールドは関数呼び出しによって 0 にリセットされるため、SQLRowCount によって返される値は SQL_DIAG_ROW_COUNT フィールドの値と異なる場合があることに注意してください。他のステートメントと関数の場合、ドライバーは *RowCountPtr で返される値を定義できます。たとえば、一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。SQL_DIAG_ROW_COUNT フィールドが設定された後に関数が呼び出された場合、SQL_DIAG_ROW_COUNT フィールドは関数呼び出しによって 0 にリセットされるため、SQLRowCount によって返される値は SQL_DIAG_ROW_COUNT フィールドの値と異なる場合があることに注意してください。他のステートメントと関数の場合、ドライバーは *RowCountPtr で返される値を定義できます。たとえば、一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。SQL_DIAG_ROW_COUNT フィールドが設定された後に関数が呼び出された場合、SQL_DIAG_ROW_COUNT フィールドは関数呼び出しによって 0 にリセットされるため、SQLRowCount によって返される値は SQL_DIAG_ROW_COUNT フィールドの値と異なる場合があることに注意してください。他のステートメントと関数の場合、ドライバーは *RowCountPtr で返される値を定義できます。たとえば、一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。SQL_DIAG_ROW_COUNT フィールドは関数呼び出しによって 0 にリセットされるため、SQLRowCount によって返される値は SQL_DIAG_ROW_COUNT フィールドの値と異なる場合があります。他のステートメントと関数の場合、ドライバーは *RowCountPtr で返される値を定義できます。たとえば、一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。SQL_DIAG_ROW_COUNT フィールドは関数呼び出しによって 0 にリセットされるため、SQLRowCount によって返される値は SQL_DIAG_ROW_COUNT フィールドの値と異なる場合があります。他のステートメントと関数の場合、ドライバーは *RowCountPtr で返される値を定義できます。たとえば、一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。一部のデータ ソースは、行をフェッチする前に、SELECT ステートメントまたはカタログ関数によって返される行数を返すことができる場合があります。注 多くのデータ ソースは、フェッチする前に結果セット内の行数を返すことができません。相互運用性を最大限に高めるために、アプリケーションはこの動作に依存すべきではありません。
doco ページの最後には、次のように表示されます。
ステートメント ハンドルで実行された最後の SQL ステートメントが UPDATE、INSERT、または DELETE ステートメントではない場合、または SQLBulkOperations への前の呼び出しの Operation 引数が SQL_ADD、SQL_UPDATE_BY_BOOKMARK、または SQL_DELETE_BY_BOOKMARK のいずれでもない場合、またはへの前の呼び出しの Operation 引数がSQLSetPos は SQL_UPDATE または SQL_DELETE ではありませんでした。*RowCountPtr の値はドライバーで定義されています。詳細については、影響を受ける行数の決定を参照してください。
バッチでラップされているため、結果が不明であることはもっともらしいと思います。
しかし、このアプリが2 年間実行されていて、この問題が一度も発生していないことを忘れることはできません。顧客は、一部のテーブル データを変更または削除した後、アプリが失敗したと述べています。ありそうもないことだと思いますが、経験から、彼らは何か他のことをしたことがわかり、何を言っているのではありません.