2009-11-06 19 views
7

Pregunta rápida sobre cursores (en particular cursores de Oracle).¿Los cursores de la base de datos recogen los cambios en los datos subyacentes?

Digamos que tengo una tabla llamada "mi_tabla" que tiene dos columnas, una ID y un nombre. Hay millones de filas, pero la columna de nombre siempre es la cadena 'prueba'.

luego ejecutar este script PL/SQL:

declare 
cursor cur is 
    select t.id, t.name 
    from my_table t 
    order by 1; 
begin 
    for cur_row in cur loop 
    if (cur_row.name = 'test') then 
     dbms_output.put_line('everything is fine!'); 
    else 
     dbms_output.put_line('error error error!!!!!'); 
     exit; 
    end if; 
    end loop; 
end; 
/

si, si bien esto se está ejecutando, ejecute este SQL:

update my_table 
    set name = 'error' 
    where id = <max id>; 
commit; 

será el cursor en el bloque PL/SQL recoger que cambian e imprimen "error error error" y salen? o no recogerá el cambio ... ¿o incluso permitirá la actualización a mi_tabla?

gracias!

+1

Tienes algún código, ¿por qué no lo ejecuta y ¿ver? –

Respuesta

11

Un cursor ejecuta efectivamente un SELECT y luego le permite iterar sobre el conjunto de resultados, que se guarda en una instantánea del estado de la base de datos. Debido a que su conjunto de resultados ya se ha obtenido, no se verá afectado por la instrucción UPDATE. (Manejo de las cosas de otro modo requeriría que vuelva a ejecutar la consulta cada vez que el cursor avanzado!)

Ver:

http://www.techonthenet.com/oracle/cursors/declare.php

+6

Si bien es cierto que el cursor no se verá afectado por la declaración de actualización, no es el caso de que todos los datos a los que accederá el cursor hayan sido previamente recuperados en la memoria. Si ese fuera el caso, a menudo tomaría mucho tiempo obtener la primera fila del cursor. Lo que sucede es que el cursor selecciona los datos "como en" el SCN que estaba vigente cuando se abrió. Es por eso que las consultas de larga ejecución a veces pueden fallar con un error de "instantánea demasiado antigua". –

+0

Excelente aclaración, Tony. Gracias. Actualizaré mi respuesta en consecuencia. –

+0

Para SYBASE ASE, comenzando con [15.7] (http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc36272.1570/html/commands/X11816.htm), usted puede declarar el cursor INSENSITIVE que: "especifica que los cambios de datos realizados independientemente del cursor no son visibles para el conjunto de resultados del cursor. Si no especifica este argumento, el valor predeterminado es semi_sensible. No puede actualizar un cursor insensible". – eric

Cuestiones relacionadas