例えば、以下のコードを考慮してください。
ResultSet rs1, rs2; Statement stmt1 = jdbcCon.createStatement(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE); rs1 = stmt1.executeQuery("SELECT * FROM SCH1.TBL1"); rs1.next(); Statement stmt2 = jdbcCon.createStatement(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE); rs2 = stmt2.executeQuery("SELECT * FROM SCH1.TBL1"); rs2.next(); PreparedStatement pStmt = jdbcCon.prepareStatement( "DELETE FROM SCH1.TBL1 WHERE CURRENT OF " + rs2.getCursorName());
SQL ステートメントが動的に実行された場合、このコードにはあいまいさはありません。 ただし、それらが静的に実行され、複数の ResultSet オブジェクトが同じ接続で開かれていた場合、問題が起きます。 pureQuery が JDBC アプリケーションの SQL ステートメントを取り込む場合、同一ステートメントは一度だけ取り込みます。 この例では pureQuery が SQL ステートメントを取り込んだ後に、pureQueryXML ファイルには SELECT * FROM SCH1.TBL1 の 1 インスタンスが含まれます。pureQuery が名前 DB_PDQ_SPC7 をカーソルに割り当てる場合、pureQueryXML ファイルにも 1 インスタンスの DELETE FROM SCH1.TBL1 WHERE CURRENT OF DB_PDQ_SPC7 が含まれます。
実行時に、WHERE CURRENT OF 節内でカーソル名だけを使用している場合、pureQuery は 2 つの ResultSet オブジェクトのどちらに DELETE ステートメントのカーソルが作用するかを判別できません。
これよりも不明瞭な状況でも、同じあいまいさが起きる可能性があります。 例えば、SELECT ステートメントが ResultSet オブジェクトを戻すメソッド内にあり、UPDATE または DELETE WHERE CURRENT OF ステートメントが ResultSet オブジェクトを入力パラメーターとして受け取るメソッド内にあるという場合があります。
問題がアプリケーションのソース・コード内にあるため明瞭でない場合もあります。 この理由から、pureQuery は、複数の ResultSet オブジェクトが現在単一の SELECT ステートメントに対して開かれていることを検出した場合の警告をログに記録します。
このあいまいさを解決するために試行できる技法があります。
Statement stmt1 = jdbcCon.createStatement(TYPE_FORWARD_ONLY,CONCUR_UPDATABLE); rs1 = stmt.executeQuery("SELECT * FROM SCH1.TBL1"); rs1.next(); Statement stmt2 = jdbcCon.createStatement(TYPE_FORWARD_ONLY,CONCUR_UPDATABLE); rs2 = stmt.executeQuery("SELECT * FROM SCH1.TBL1"); rs2.next(); rs2.deleteRow();
同一の静的 SQL SELECT ステートメントを DB2 for z/OS に対して実行し、複数の同一の ResultSet オブジェクトを開く必要がある場合、まず IBM Data Server Driver for JDBC and SQLJ のプロパティー db2.jcc.allowSqljDuplicateStaticQueries を YES または TRUE に設定する必要があります。