domingo, 7 de agosto de 2011

CURSOR IMPLICITO


ATRIBUTOS EN CURSORES IMPLICITOS

Oracle abre implícitamente un cursor cuando procesa un comando SQL que no este asociado a un cursor implícito. El cursor implícito se llama SQL y dispone también de los cuatro atributos mencionados, que pueden facilitarnos información sobre la ejecución de los comandos SELECT INTO, INSERT, UPDATE Y DELETE.

El valor de los atributos del cursor SQL se refieren, en cada momento, a la ultima orden SQL:
-         SQL%NOTROUND dará TRUE si el ultimo INSERT, UPDATE, DELETE O SELECT INTO han fallado (no han afectado a ninguna fila).
-         SQL%FOUND dará TRUE si el ultimo INSERT, UPDATE, DELETE O SELECT INTO han afectado a una o mas filas.
-         SQL%ROWCOUNT devuelve el numero de filas afectadas por el ultimo INSERT, UPDATE, DELETE O SELECT INTO.
-         SQL%ISOPEN siempre devolverá FALSO, ya que ORACLE cierra automáticamente el cursor después de cada orden SQL.
Es preciso hacer unas observaciones respecto al uso de atributos en cursores implícitos: el comportamiento de los atributos en los cursores implícitos es distinto al de los cursores explícitos. De hecho, como acabamos de ver, el cursor estara cerrado inmediatamente después de procesar la orden SELECT…INTO,  que es cuando se pregunta por su atributo o atributos (lo cual debería determinar una situación de error).

A continuación se especifican algunas peculiaridades en el comportamiento y uso de los atributos en cursores implícitos:
- Devolverán un valor relativo a la ultima orden INSERT, UPDATE, DELETE O SELECT INTO, aunque el cursor este cerrado.
- En el caso de que se trate de un SELECT…INTO, debemos tener en cuenta que a de devolver una fila  y sólo una, pues de lo contrario se producirá un error y se levantará automáticamente una excepción:
- NO_DATA_FOUND si la consulta no devuelve ninguna fila.
- TOO_MANY_ROWS si la consulta devuelve mas de una fila.

Se detendrá la ejecución normal del programa y bifurcará a la sección EXCEPTION.
Por tanto, cualquier comprobación de la situación del cursor en esas circunstancias resulta inútil.

-         Lo indicado en el parrafo anterior no es aplicable a las ordenes INSERT, UPDATE, DELETE, ya que en estos casos no se levantan las excepciones correspondientes.
El siguiente ejemplo ilustra estas observaciones:

DECLARE
v_dpto depart.dnombre%TYPE;
v_loc depart.loc%TYPE;
BEGIN
V_dpto:=’marketing’;         ------------- (no existe marketing)
UPDATE depart SET loc = ’sevilla’   
 WHERE dnombre=v_dpto;     --------- fallará
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Error en la actualización’);
END IF;
DBMS_OUTPUT.PUT_LINE(‘Continua el programa’);
SELECT loc INTO v_loc
FROM depart
WHERE dnombre = v_dpto;     ---------- fallará
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Imposible!  Nuca pasará por aquí’);
END IF;
END;

El resultado de la ejecución del programa será:
Error en la actualización
Continúa el programa
…..
ORA-014003: no se han encontrado datos
ORA-065112: en línea 12

Cuando un SELECT INTO hace referencia a una función de grupo nunca se levantará la excepción NO_DATA_FOUND, Y SQL%FOUND siempre será verdadero. Esto se debe a que las funciones de grupo siempre retornan algún valor (aunque sea NULL).

BEGIN
…….
SELECT MAX(salario) INTO v_max
FROM emple
WHERE dept_no = num_depart;  ------------- nunca levantará NO_DATA_FOUND
IF SQL%NOTFOUND THEN      ------------- nunca será cierto
…….
END IF;
EXCEPTION
WHEN  NO_DATA_FOUND THEN   -------------- no será invocada
……….


No hay comentarios:

Publicar un comentario