トップ回答者
SQL の GROUP BY 句を用いて集計した照会結果を Recordset オブジェクトに LockType =adLockOptimistic で格納して参照しようとすると 「SQL0100W FETCH、UPDATE または DELETE の対象となる行がないか、または照会の結果が空の表です。 」のエラーが返される。

質問
-
■環境
OS : Windows Server 2016 64bit (IBM DB2 ODBC DRIVERをインストール)
開発言語 : VB.NET(Visual Studio 2017, Microsoft ActiveX Data Objects2.8 Library)
DBMS: DB2 V11.1
■質問の背景
・VB6(Microsoft ActiveX Data Objects2.5 Library)+DB2 V7.2の環境で開発されていたプログラムを
VB.NET+DB2 V11.1にコンバージョンするプロジェクトを実施しています。
プログラムの作りとして、DB2への接続はODBC接続を利用しており、VB.NET 化に
おいても同様のODBC接続でDB2に接続する仕様とします。
■現在発生している事象
■問題
・プログラムではデータベースにアクセスして Open メソッドを使用して SQL の実行結果を Recordset オブジェクト (ADODB.Recordset)に格納しています。
・SQL では GROUP BY 句を用いて集計した結果を取得していますが、 Open メソッドの LockType プロパティは adLockOptimistic(共有的ロック)に設定しています。
・上記の Recordset オブジェクトのレコードを MoveNext メソッドで次のレコードに移動して参照していくと、以下のエラーが返されてレコードを参照できなくなります。
「エラー番号:-2147467259,[IBM][CLI Driver][DB2/NT64] SQL0100W FETCH、UPDATE または DELETE の対象となる行がないか、または照会の結果が空の表です。 SQLSTATE=02000,(Microsoft OLE DB Provider for ODBC Drivers)」
・参照しようとしたレコードが元の表でも単一のレコードである場合は上記のエラーが発生せず正常に参照でき、複数のレコードを集計した結果である場合は上記のエラーが発生することが判明しています。
【コード】
'ADO RECORDSET OPENメソッド発行
adoRsMthAtmRslt = New ADODB.Recordset
Call adoRsMthAtmRslt.Open(strSQL, adoConnect, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockOptimistic, ADODB.CommandTypeEnum.adCmdText)
■調査済み回避策
①VB6+DB2 V7.2で実行すると正常に動作し、上記エラーは発生しない。
②Open メソッドの LockType プロパティを adLockReadOnly (読み取り専用)に変更すると上記のエラーは発生せず、正常に動作する。
■質問
・VB6 と VB.NET とで、LockType プロパティを adLockOptimistic とした場合に Recordset オブジェクトの挙動が異なる(MoveNext メソッドでエラーが発生する)ことがあるのでしょうか。
・上記のエラー事象の回避策として、上述の調査済み回避策の②を想定していますが、他に方法はあるでしょうか。
回答
-
.NET から Recordset を使うと、使用済みオブジェクトの解放処理(Marshal.ReleaseComObject)が求められたりするので、個人的にはお奨めしませんが、それはさておき。
そもそも本当に動的カーソル(adOpenDynamic)が必要かどうかを検討した方が良いと思います。このカーソルタイプをサポートしているドライバーは非常に稀であるためです。(実装するにしても、競合時のエラー処理が煩雑になりがちですし…)
たとえば、かわりにキーセットカーソル(adOpenKeyset)を指定するのでは駄目でしょうか? このカーソルは多くのドライバーでサポートされています。
もしどうしてもサーバー側の動的変更にも対応したいのであれば、静的カーソル(adOpenStatic)を選択した上で、Resync メソッドで同期を取るという方法も考えられます。
それと、サポートされる CursorType と LockType の組み合わせというものは、使用している OLE DB Driver / ODBC Driver によっても異なります。もしもサポートされない組み合わせを指定して Open した場合、Recordset のこれらのプロパティは、Open 後に別の値に補正されることがあります。CursorLocation / CursorType / LockType の 3 値の組み合わせが適切な指定であるかどうか確認するため、この 3 つのプロパティの値が変化していないか、Open 前後で比較しておいた方が良いでしょう。
- 編集済み 魔界の仮面弁士MVP 2019年11月19日 13:22 訂正:Keyset と Static が逆になっていた
- 回答としてマーク kogiso99 2019年11月21日 13:33
-
DB2 はわかりませんが、メッセージで検索すると以下が引っ掛かりました。
「DB2のクライアントを7.1から8.1に変更した時に出るエラーについて」
https://qa.itmedia.co.jp/qa1114757.html
を見ると ODBC に何やら設定があるらしいです。
「DB2 and ODBC - Function sequence error」
https://bytes.com/topic/db2/answers/647506-db2-odbc-function-sequence-error
Patch1 CLI/ODBC の 1024 がどーのこーのというお話のようです。Patch1 CLI/ODBC で検索すると
「Patch1 CLI/ODBC 構成キーワード」
https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.7.0/com.ibm.db2.luw.apdv.cli.doc/doc/r0008804.html
1024 は、何やら Visual Basic に関連したパラメタのようです。
VB6 と VB.NET は同じ DSN を使用しているのでしょうか?
違うのであれば VB6 で使用している DSN の設定を確認してみてください。
- 回答としてマーク kogiso99 2019年11月21日 13:33
すべての返信
-
.NET から Recordset を使うと、使用済みオブジェクトの解放処理(Marshal.ReleaseComObject)が求められたりするので、個人的にはお奨めしませんが、それはさておき。
そもそも本当に動的カーソル(adOpenDynamic)が必要かどうかを検討した方が良いと思います。このカーソルタイプをサポートしているドライバーは非常に稀であるためです。(実装するにしても、競合時のエラー処理が煩雑になりがちですし…)
たとえば、かわりにキーセットカーソル(adOpenKeyset)を指定するのでは駄目でしょうか? このカーソルは多くのドライバーでサポートされています。
もしどうしてもサーバー側の動的変更にも対応したいのであれば、静的カーソル(adOpenStatic)を選択した上で、Resync メソッドで同期を取るという方法も考えられます。
それと、サポートされる CursorType と LockType の組み合わせというものは、使用している OLE DB Driver / ODBC Driver によっても異なります。もしもサポートされない組み合わせを指定して Open した場合、Recordset のこれらのプロパティは、Open 後に別の値に補正されることがあります。CursorLocation / CursorType / LockType の 3 値の組み合わせが適切な指定であるかどうか確認するため、この 3 つのプロパティの値が変化していないか、Open 前後で比較しておいた方が良いでしょう。
- 編集済み 魔界の仮面弁士MVP 2019年11月19日 13:22 訂正:Keyset と Static が逆になっていた
- 回答としてマーク kogiso99 2019年11月21日 13:33
-
DB2 はわかりませんが、メッセージで検索すると以下が引っ掛かりました。
「DB2のクライアントを7.1から8.1に変更した時に出るエラーについて」
https://qa.itmedia.co.jp/qa1114757.html
を見ると ODBC に何やら設定があるらしいです。
「DB2 and ODBC - Function sequence error」
https://bytes.com/topic/db2/answers/647506-db2-odbc-function-sequence-error
Patch1 CLI/ODBC の 1024 がどーのこーのというお話のようです。Patch1 CLI/ODBC で検索すると
「Patch1 CLI/ODBC 構成キーワード」
https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.7.0/com.ibm.db2.luw.apdv.cli.doc/doc/r0008804.html
1024 は、何やら Visual Basic に関連したパラメタのようです。
VB6 と VB.NET は同じ DSN を使用しているのでしょうか?
違うのであれば VB6 で使用している DSN の設定を確認してみてください。
- 回答としてマーク kogiso99 2019年11月21日 13:33