Oracle
 sql >> Database >  >> RDS >> Oracle

Tipo JDBC Scorrimento insensibile e sensibile

Come con altre funzioni che non funzionano devi leggere il documentazione prima di usarli.

L'importante è il concetto di finestra

Quindi, per osservare il cambiamento di ogni singola riga, devi impostare la dimensione di recupero a 1.

Nota che non è sufficiente impostare la dimensione di recupero per il resultSet , perché la dimensione di recupero predefinita è 10 e la modifica è valida solo per l'undicesima e le righe successive.

Pertanto la dimensione del recupero deve essere impostata su 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

Ora su ogni chiamata di rs.next() viene aperta una nuova finestra, che porta a una chiamata interna di refreshRow

che ottiene i valori correnti dal database.

Nota che questo comportamento viene eseguito solo per TYPE_SCROLL_SENSITIVE per TYPE_SCROLL_INSENSITIVE no refreshRow viene chiamato, quindi puoi vedere i dati costanti della query iniziale anche se cambi finestra. Puoi chiamare refreshRow espressamente per vedere lo stesso effetto.

Tecnicamente la funzionalità è implementata utilizzando due cursori. Il primo corrisponde alla query utilizzata, aggiungendo solo la colonna ROWID.

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

Il secondo cursore chiamato su ogni interruttore della finestra (cioè per dimensione del recupero =1 per ogni riga recuperata) si unisce al rowid salvato con la query dal primo cursore per recuperare i dati correnti.

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 

Ci sono domande simili là fuori, ma nessuna spiega davvero il problema, quindi non contrassegno questa domanda come duplicata:

Comportamento di ResultSet.TYPE_SCROLL_SENSITIVE

JDBC ResultSet Type_Scroll_Sensitive

Tipo di set di risultati JDBC sensibile allo scorrimento

La risposta breve è che la dimensione di recupero predefinita che hai utilizzato è troppo alta per osservare un aggiornamento di una singola riga .

Il test è stato eseguito su Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 DriverVersion 12.2.0.1.0