Documente Academic
Documente Profesional
Documente Cultură
PL/SQL EN ORACLE
PL / SQL
CURSORES
CURSORES
Si una sentencia SELECT devuelve ms de una fila*,
CURSOR
Sintaxis:
CURSOR nombre_cursor -- Se declara
IS consulta SQL;
OPEN nombre_cursor; -- Se abre
FETCH nombre_cursor
INTO var1,var2, ..., varn;
/*Se recupera la fila actual */
CLOSE nombre_cursor; -- Se cierra
CURSOR
Atributos (funciones) de los cursores:
%NOTFOUND: Es verdadero (TRUE) cuando el ltimo
FETCH ejecutado no recupera datos
%FOUND: Es verdadero cuando el ltimo FETCH ejecutado
recuper datos (trajo una fila)
%ROWCOUNT: Devuelve el nmero de filas ledas hasta el
momento
%ISOPEN: Es verdadero cuando el cursor est abierto
EJEMPLO CURSOR
DROP TABLE empleado;
CREATE TABLE empleado(
codigo NUMBER(8) PRIMARY KEY,
nombre VARCHAR2(15),
dep NUMBER(3),
sueldo NUMBER(8) NOT NULL
);
INSERT INTO empleado VALUES(12, 'Patty',1,100);
INSERT INTO empleado VALUES(15, 'Adam',2,300);
INSERT INTO empleado VALUES(76, 'Adrian',2,400);
INSERT INTO empleado VALUES(73, 'Ben',5,500);
INSERT INTO empleado VALUES(56, 'Lisa',3,100);
Ejemplo Cursor
DECLARE
CURSOR ordena_d IS
SELECT codigo, dep FROM empleado ORDER BY dep;
codi empleado.codigo%TYPE;
dpto empleado.dep%TYPE;
BEGIN
OPEN ordena_d;
LOOP
FETCH ordena_d INTO codi, dpto;
EXIT WHEN ordena_d%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(codi || '--' || dpto);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Total de Registros: ' || ordena_d%ROWCOUNT);
CLOSE ordena_d;
END;
/
CURSORES
Los cursores tambin se pueden procesar sin necesidad de abrirlos, ni
hacerles FETCH, ni cerrarlos explcitamente.
Estas acciones las puede hacer automticamente un ciclo FOR as:
DECLARE
CURSOR ordena_d IS --Se declara el cursor
SELECT codigo, dep FROM empleado ORDER BY dep;
BEGIN
FOR mi_e IN ordena_d LOOP
DBMS_OUTPUT.PUT_LINE(mi_e.codigo || ' ' || mi_e.dep);
END LOOP;
---DBMS_OUTPUT.PUT_LINE('Total: ' || ordena_d%ROWCOUNT);
END;
/
mi_e es una variable local del ciclo que
automticamente se declara del tipo del cursor
ROWTYPE
Se puede declarar una variable del tipo de una tabla
(mediante ROWTYPE)y se puede usar as:
DECLARE
CURSOR emp_cur IS SELECT * FROM empleado;
mi_e empleado%ROWTYPE;
BEGIN
OPEN emp_cur;
Todos los datos de un
LOOP
empleado quedan almacenados
en mi_e
FETCH emp_cur INTO mi_e;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(mi_e.codigo || ' ' || mi_e.dep);
END LOOP;
CLOSE emp_cur;
END;
/
DECLARE
CURSOR ord_c IS
SELECT sueldo FROM empleado ORDER BY sueldo DESC;
mi_e ord_c%ROWTYPE;
suma NUMBER(6) := 0;
BEGIN
OPEN ord_c;
LOOP
FETCH ord_c INTO mi_e;
EXIT WHEN ord_c%NOTFOUND OR ord_c%ROWCOUNT = 3;
suma := suma + mi_e.sueldo;
END LOOP;
CLOSE ord_c;
DBMS_OUTPUT.PUT_LINE('Total: ' || suma );
END;
/
Qu hace este cdigo?
DECLARE
CURSOR emp_c IS SELECT dep FROM empleado FOR UPDATE;
BEGIN
FOR UPDATE bloquea las filas ledas por
FOR mi_e IN emp_c
el cursor antes* de hacer el UPDATE o
LOOP
el DELETE
IF mi_e.dep = 2 THEN
DELETE FROM empleado -- Se borran los emps actuales del depto 2
WHERE CURRENT OF emp_c; -- Se refiere a la fila actual del cursor
ELSE
UPDATE empleado SET dep = dep - 1
Para usar CURRENT OF el cursor
WHERE CURRENT OF emp_c;
debe ser FOR UPDATE.
END IF;
END LOOP;
* Si no hay FOR UPDATE, Oracle bloquea las filas en el momento de hacer el
END;
UPDATE o el DELETE. FOR UPDATE establece el bloqueo desde el OPEN.
/