Oracle
 sql >> Base de données >  >> RDS >> Oracle

Défilement de type JDBC insensible et sensible

Comme avec d'autres fonctionnalités qui ne fonctionnent pas vous devez lire le documentation avant de les utiliser.

L'important c'est la notion de fenêtre

Donc, pour observer le changement de chaque ligne, vous devez définir la taille de récupération à 1.

Notez qu'il ne suffit pas de définir la taille de récupération pour le resultSet , car la taille de récupération par défaut est 10 et la modification n'est valide que pour la 11e ligne et les lignes suivantes.

Par conséquent, la taille de récupération doit être définie sur le prepareStatement :

 def stmt = con.prepareStatement("""select id, val from test
 where  id between ? and ?  order by id""", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)
 stmt.setFetchSize(1)
 // set bind variables and execute statement

Maintenant à chaque appel de rs.next() une nouvelle fenêtre s'ouvre, ce qui conduit à un appel interne de refreshRow

qui obtient les valeurs actuelles de la base de données.

Notez que ce comportement n'est effectué que pour TYPE_SCROLL_SENSITIVE pour TYPE_SCROLL_INSENSITIVE pas de refreshRow est appelé, ainsi vous voyez les données constantes de la requête initiale même si vous changez de fenêtre. Vous pouvez appeler refreshRow explicitement pour voir le même effet.

Techniquement, la fonctionnalité est implémentée à l'aide de deux curseurs. La première correspond à la requête utilisée, en ajoutant uniquement la colonne ROWID.

 select rowid as "__Oracle_JDBC_internal_ROWID__", id, val from test
 where  id between :1  and :2   order by id

Le deuxième curseur appelé sur chaque commutateur de fenêtre (c'est-à-dire pour la taille de récupération =1 pour chaque ligne récupérée) jointure externe simple le rowid enregistré avec la requête du premier curseur pour récupérer les données actuelles.

WITH "__JDBC_ROWIDS__" AS (SELECT COLUMN_VALUE ID, ROWNUM NUM FROM TABLE(:1 ))
SELECT "__JDBC_ORIGINAL__".*
FROM (select rowid as "__Oracle_JDBC_internal_ROWID__", id, val from test
where  id between :2  and :3   order by id) "__JDBC_ORIGINAL__", "__JDBC_ROWIDS__"
WHERE "__JDBC_ORIGINAL__"."__Oracle_JDBC_internal_ROWID__"(+) = "__JDBC_ROWIDS__".ID
ORDER BY "__JDBC_ROWIDS__".NUM 

Il existe des questions similaires, mais aucune d'entre elles n'explique vraiment le problème, donc je ne marque pas cette question comme étant en double :

Comportement de ResultSet.TYPE_SCROLL_SENSITIVE

JDBC ResultSet Type_Scroll_Sensitive

Type de jeu de résultats JDBC sensible au défilement

La réponse courte est que la taille de récupération par défaut que vous avez utilisée est trop élevée pour observer une mise à jour d'une seule ligne .

Le test a été effectué sur Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 DriverVersion 12.2.0.1.0