Es liegt beispielsweise folgender Code vor:
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());
Wenn die SQL-Anweisungen dynamisch ausgeführt werden, stellt dieser Code keine Mehrdeutigkeit dar. Wenn sie jedoch statisch ausgeführt werden und die ResultSet-Objekte mit derselben Verbindung geöffnet wurden, tritt ein Problem auf. Wenn pureQuery SQL-Anweisungen für eine Nicht-pureQuery-API-Anwendung erfasst, werden identische Anweisungen nur einmal erfasst. Nachdem pureQuery die SQL-Anweisungen in diesem Beispiel erfasst, enthält die pureQueryXML-Datei eine Instanz von SELECT * FROM SCH1.TBL1. Wenn pureQuery dem Cursor den Namen DB_PDQ_SPC7 zuordnet, enthält die pureQueryXML-Datei auch eine Instanz von DELETE FROM SCH1.TBL1 WHERE CURRENT OF DB_PDQ_SPC7.
Wenn nur der Cursorname in der Klausel WHERE CURRENT OF während der Ausführung verwendet wird, kann pureQuery nicht feststellen, auf welche der beiden ResultSet-Objekte sich der Cursor in der Anweisung DELETE auswirkt.
Dieselbe Mehrdeutigkeit kann in weniger offensichtlichen Situationen auftreten. Beispielsweise können sich die SELECT-Anweisungen in Methoden befinden, die ResultSet-Objekte zurückgeben, und die UPDATE- oder DELETE WHERE CURRENT OF-Anweisungen können sich in Methoden befinden, die ResultSet-Objekte als Eingabeparameter empfangen.
Das Problem kann auch im Quellcode einer Anwendung nicht offensichtlich sein. Aus diesem Grund protokolliert pureQuery eine Warnung, wenn festgestellt wird, dass zu einem Zeitpunkt mehrere ResultSet-Objekte für eine einzige Anweisung SELECT geöffnet sind.
Mit den folgenden Verfahren können Sie versuchen, diese Mehrdeutigkeit zu beheben.
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();
PreparedStatement pStmt = jdbcCon.prepareStatement( "DELETE FROM SCH1.TBL1 WHERE CURRENT OF " + rs2.getCursorName());Während der Ausführung kann pureQuery die Methode getCursorName() der Anweisung UPDATE oder DELETE zuordnen und ordnet daher der Anweisung das richtige Objekt ResultSet zu. Diese Zuordnung wird jedoch nur sichergestellt, wenn sich die Methode getCursorName() an einer der beiden folgenden Positionen befindet:
Wenn Sie identische statische SQL-Anweisungen SELECT für DB2 for z/OS ausführen müssen und mehrere identische ResultSet-Objekte öffnen müssen, müssen Sie zuerst die IBM® Data Server Driver für JDBC und SQLJ-Eigenschaft db2.jcc.allowSqljDuplicateStaticQueries auf YES oder TRUE setzen.