Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Rolagem do tipo JDBC insensível e sensível


Assim como outros recursos que não funcionam você deve ler o documentação antes de usá-los.

O importante é a noção da janela

Portanto, para observar a mudança de cada linha, você deve definir o tamanho da busca para 1.

Observe que não é suficiente definir o tamanho da busca para o resultSet , porque o tamanho de busca padrão é 10 e a alteração é válida apenas para a 11ª e as linhas subsequentes.

Portanto, o tamanho da busca deve ser definido no 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

Agora em cada chamada de rs.next() uma nova janela é aberta, o que leva a uma chamada interna de refreshRow

que obtém os valores atuais do banco de dados.

Observe que este comportamento é realizado somente para TYPE_SCROLL_SENSITIVE para TYPE_SCROLL_INSENSITIVE sem refreshRow é chamado, então você vê os dados constantes como da consulta inicial, mesmo que você alterne a janela. Você pode chamar refreshRow explicitamente para ver o mesmo efeito.

Tecnicamente, a funcionalidade é implementada usando dois cursores. A primeira corresponde à consulta utilizada, adicionando apenas a coluna ROWID.
 select rowid as "__Oracle_JDBC_internal_ROWID__", id, val from test
 where  id between :1  and :2   order by id

O segundo cursor chamado em cada switch de janela (ou seja, para buscar tamanho =1 para cada linha buscada) simples une o rowid salvo com a consulta do primeiro cursor para buscar novamente os dados atuais.
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 

Existem perguntas semelhantes por aí, mas nenhuma delas realmente explica o problema, então não marquei esta pergunta como duplicada:

Comportamento de ResultSet.TYPE_SCROLL_SENSITIVE

JDBC ResultSet Type_Scroll_Sensitive

tipo de conjunto de resultados JDBC sensível à rolagem

A resposta curta é que o tamanho de busca padrão que você usou é alto demais para observar uma atualização de uma única linha .

O teste foi feito noOracle Database 12c Enterprise Edition Release 12.2.0.1.0 DriverVersion 12.2.0.1.0