Par exemple, imaginons le code suivant :
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());
Si les instructions SQL sont exécutées en mode dynamique, ce code ne comporte pas d'ambiguïtés. Toutefois, si elles sont exécutées en mode statique et que les objets ResultSet sont ouverts avec la même connexion, un problème survient. Lorsque pureQuery capture les instructions SQL d'une application non-pureQuery, il capture des instructions identiques une seule fois. Une fois les instructions SQL capturées par pureQuery dans cet exemple, le fichier pureQueryXML contient une instance de SELECT * FROM SCH1.TBL1. Si pureQuery attribue le nom DB_PDQ_SPC7 au curseur, le fichier pureQueryXML contient également une instance de DELETE FROM SCH1.TBL1 WHERE CURRENT OF DB_PDQ_SPC7.
Lors de l'exécution, si vous utilisez uniquement le nom du curseur dans la clause WHERE CURRENT OF, pureQuery ne peut pas déterminer l'objet ResultSet sur lequel le curseur de l'instruction DELETE agit.
Les mêmes ambiguïtés peuvent être relevées dans des situations moins évidentes. Par exemple, les instructions SELECT peuvent se trouver dans des méthodes retournant des objets ResultSet et les instructions UPDATE ou DELETE WHERE CURRENT OF peuvent se trouver dans des méthodes recevant des objets ResultSet comme paramètres d'entrée.
Le problème peut ne pas être évident dans un code source d'application. Voilà pourquoi pureQuery consigne un avertissement lorsqu'il détecte plusieurs objets ResultSet actuellement ouverts pour une seule instruction SELECT.
Voici des techniques permettant de lever toute ambiguïté.
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());
Lors de l'exécution, pureQuery peut associer la méthode getCursorName() à l'instruction UPDATE ou DELETE et, par conséquent, associer l'objet ResultSet correct à l'instruction.
Cette association est garantie uniquement lorsque la méthode getCursorName() apparaît dans l'un de ces deux points :Si vous devez exécuter des instructions SQL SELECT statiques identiques dans DB2 for z/OS et ouvrir plusieurs objets ResultSet identiques, commencez par définir la propriété IBM® pour JDBC et SQLJ db2.jcc.allowSqljDuplicateStaticQueries sur YES ou TRUE.