You are on page 1of 6

CLASE I

OBTENER DATOS DEL CURSOR

/*En el bloque PL/SQL del ejemplo, el cursor cur_emp obtiene la identificacin y


apellido de los empleados que trabajan en el departamento 30. En la seccin de
Ejecucin se abre el cursor, se lee la primera fila y los valores son almacenados
en las variables declaras para posteriormente mostrar la informacin. Para poder
leer todas las filas recuperadas en el cursor, se debe generar una Iteracin.*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID =30;
V_LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
V_EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
BEGIN
OPEN CUR_EMP;
FETCH CUR_EMP INTO V_EMPNO, V_LNAME;
DBMS_OUTPUT.PUT_LINE(V_EMPNO || ' ' || V_LNAME);
END;

/*En el ejemplo ahora se utiliza un loop simple para leer todas las filas del
cursor. Se utiliza tambin el atributo de cursor %NOTFOUND para la condicin de
salida del loop.*/

DECLARE
CURSOR C_EMP_CURSOR IS
SELECT EMPLOYEE_ID, LAST_NAME FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID =30;
V_EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
V_LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
BEGIN
OPEN C_EMP_CURSOR;
LOOP
FETCH C_EMP_CURSOR INTO V_EMPNO, V_LNAME;
EXIT WHEN C_EMP_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( V_EMPNO ||' '||V_LNAME);
END LOOP;
END;

Cerrar el Cursor

/*Un cursor puede ser reabierto slo si ste est cerrado. Si se leen datos desde
un cursor despus de que ste se ha cerrado entonces la excepcin INVALID_CURSOR
se producir. El nmero de cursores abiertos por sesin es determinado por el
parmetro de la Base de Datos OPEN_CURSORS. Por defecto es 50.*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES WHERE DEPARTMENT_ID =30;
LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
BEGIN
OPEN CUR_EMP;
FETCH EMP_CURSOR INTO EMPNO, LNAME;
DBMS_OUTPUT.PUT_LINE(EMPNO || ' ' || LNAME);
CLOSE CUR_EMP;
END;
Atributos %ROWCOUNT y %NOTFOUND

/*En el ejemplo, el bloque obtiene a todos los empleados que existen en la table
HR.EMPLOYEES. La condicin para salir del loop de lectura del cursor es que las
filas leda sea mayor a 10 o que ya no existan ms filas que leer en el cursor.*/

DECLARE
V_EMPLEADO VARCHAR2(60);
CURSOR CUR_EMP IS
SELECT FIRST_NAME || ' ' || LAST_NAME
FROM HR.EMPLOYEES;
BEGIN
OPEN CUR_EMP;
LOOP
FETCH CUR_EMP INTO V_EMPLEADO;
EXIT WHEN CUR_EMP%ROWCOUNT > 10 OR
CUR_EMP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_EMPLEADO);
END LOOP;
CLOSE CUR_EMP;
END;

Cursores y Registros

/*se define el registro reg_emp basado en las columnas seleccionadas por el cursor
cur_emp (identificacin y apellido de los empleados del departamento 30). Al leer
las filas del cursor los valores son almacenados en los campos del registro
declarado. Los nombres de Los campos del registro son los nombres de las columnas
obtenidas en el cursor (employee_id y last_name).*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID = 30;
REG_EMP CUR_EMP%ROWTYPE;
BEGIN
OPEN CUR_EMP;
LOOP
FETCH CUR_EMP INTO REG_EMP;
EXIT WHEN CUR_EMP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(REG_EMP.EMPLOYEE_ID || ' ' || REG_EMP.LAST_NAME);
END LOOP;
CLOSE CUR_EMP;
END;
Manejo del Cursor: Loop Simple

/*En el bloque PL/SQL del ejemplo, se lee desde el cursor cur_emp la identificacin
y apellido de los empleados que trabajan en el departamento 30. La informacin se
muestra hasta cuando no existan ms filas que leer desde el cursor cur_emp.*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES WHERE DEPARTMENT_ID =30;
LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
BEGIN
OPEN CUR_EMP;
LOOP
FETCH EMP_CURSOR INTO EMPNO, LNAME;
EXIT WHEN CUR_EMP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(EMPNO || ' ' || LNAME);
END LOOP;
CLOSE CUR_EMP;
END;

Manejo del Cursor: WHILE LOOP

/*En el ejemplo, se hace una primera lectura del cursor cur_emp para poder validar
en la condicin si existen filas que leer antes de comenzar con la iteracin. Por
lo tanto mientras existan filas que leer desde el cursor se mostrar la informacin.
Cuando ya no existan ms filas que leer termina la iteracin del bucle WHILE LOOP
y se cierra el cursor.*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME FROM HR.EMPLOYEES WHERE DEPARTMENT_ID =30;
EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
BEGIN
OPEN CUR_EMP;
FETCH CUR_EMP INTO EMPNO, LNAME;
WHILE CUR_EMP%FOUND LOOP
DBMS_OUTPUT.PUT_LINE( EMPNO ||' '||LNAME);
FETCH EMP_CURSOR INTO EMPNO, LNAME;
END LOOP;
CLOSE CUR_EMP;
END;

Manejo del Cursor: FOR LOOP

/*En el ejemplo, se lee cada una de las filas del cursor cur_emp y los valores se
almacenan en el registro reg_emp cuyos campos sern employee_id y last_name que son
las columnas seleccionadas en el cursor. Cuando no existen ms filas que leer, el
ciclo finaliza y se cierra el cursor. Declarar el registro reg_emp, abrir el cursor
cur_emp, leer sus datos, finalizar el loop y cerrar el cursor se ejecutan en forma
implcita utilizando FOR LOOP.*/

DECLARE
CURSOR CUR_EMP IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES WHERE DEPARTMENT_ID =30;
BEGIN
FOR REG_EMP IN CUR_EMP LOOP
DBMS_OUTPUT.PUT_LINE( REG_EMP.EMPLOYEE_ID || ' ' || REG_EMP.LAST_NAME);
END LOOP;
END;
CLASE II
Cursor FOR LOOP usando Subconsultas

/*El ejemplo el registro emp_record almacena los empleados que trabajan en el


departamento 30 los que son obtenidos usando una subconsulta. Luego, a travs del
loop, se mostrar toda la informacin almacenada en el registro.*/

BEGIN
FOR EMP_RECORD IN (SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID =30)
LOOP
DBMS_OUTPUT.PUT_LINE( EMP_RECORD.EMPLOYEE_ID ||' '||EMP_RECORD.LAST_NAME);
END LOOP;
END;

Cursores con Parmetros

/*El bloque del ejemplo posee un cursor con parmetro p_deptno que segn el valor
que se le asigne cuando se abra obtendr informacin de los empleados que
trabajen en el departamento asignado por parmetro. En este caso se muestran los
empleados que trabajan en el departamento 30 y 20.*/

DECLARE
CURSOR EMP_CURSOR (P_DEPTNO NUMBER) IS
SELECT EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID = P_DEPTNO;
V_EMPNO HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
V_LNAME HR.EMPLOYEES.LAST_NAME%TYPE;
BEGIN
OPEN EMP_CURSOR (30);
DBMS_OUTPUT.PUT_LINE('Empleados Depto 30');
LOOP
FETCH EMP_CURSOR INTO V_EMPNO, V_LNAME;
EXIT WHEN EMP_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(' ' || RPAD(V_EMPNO, 19, ' ') ||' '||V_LNAME);
END LOOP;
CLOSE EMP_CURSOR;
OPEN EMP_CURSOR (20);
DBMS_OUTPUT.NEW_LINE();
DBMS_OUTPUT.PUT_LINE('Empleados Depto 20');
LOOP
FETCH EMP_CURSOR INTO V_EMPNO, V_LNAME;
EXIT WHEN EMP_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(' ' || RPAD(V_EMPNO, 19, ' ') ||' '|| V_LNAME);
END LOOP;
CLOSE EMP_CURSOR;
END;
Clusula WHERE CURRENT Y FOR UPDATE

/*El bloque del ejemplo obtiene las filas completas de los empleados que trabajan
en el departamento 100. Al abrir el cursor FOR UPDATE se bloquean todas sus filas
en la table (las filas que poseen el departamento 100). Despus de cerrar el cursor,
con la instruccin COMMIT se liberan las filas recuperadas por el cursor en la
tabla original.*/

DECLARE
EMPLEADO HR.EMPLOYEES%ROWTYPE;
CURSOR EMP_CURSOR IS
SELECT *
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID = 100
FOR UPDATE;
BEGIN
OPEN EMP_CURSOR; -- Se produce el bloqueo
LOOP
FETCH EMP_CURSOR INTO EMPLEADO;
EXIT WHEN EMP_CURSOR%NOTFOUND;
IF EMPLEADO.SALARY < 7000 THEN
UPDATE HR.EMPLOYEES
SET SALARY=SALARY + SALARY *.10
WHERE CURRENT OF EMP_CURSOR;
END IF;
END LOOP;
CLOSE EMP_CURSOR; -- No libera bloqueos
COMMIT; /*Libera el bloqueo de las filas del cursor FOR UPDATE*/
END ;

Cursores con Subconsultas

/*El bloque del ejemplo, muestra a los empleados que posean un salario menor al
salario promedio. (El resultado se muestra en la siguiente pgina).*/

DECLARE
CURSOR MI_CURSOR IS
SELECT FIRST_NAME || ' ' || LAST_NAME, SALARY
FROM HR.EMPLOYEES
WHERE SALARY < (SELECT ROUND(AVG(SALARY))
FROM HR.EMPLOYEES)
ORDER BY SALARY, LAST_NAME;
NOMBRE VARCHAR2(50);
SALARIO HR.EMPLOYEES.SALARY%TYPE;
BEGIN
OPEN MI_CURSOR;
DBMS_OUTPUT.PUT_LINE(' FUNCIONARIOS CON SALARIO MENOR AL PROMEDIO ');
DBMS_OUTPUT.PUT_LINE(' ---------------------------------------- ');
LOOP
FETCH MI_CURSOR INTO NOMBRE, SALARIO;
EXIT WHEN MI_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(RPAD(NOMBRE, 25, ' ' ) || ' : ' || TO_CHAR(SALARIO,
'$999,999'));
END LOOP;
CLOSE MI_CURSOR;
END;
Trabajando con ms de un Cursor

/*En el ejemplo, por cada departamento ledo (primer cursor) se leen desde el
segundo cursor todos los empleados que pertenecen al departamento. Una vez ledos
todos los empleados se lee el siguiente departamento para obtener los empleados del
nuevo departamento ledo y as sucesivamente hasta cuando ya no existan ms
departamentos que leer desde el cursor principal.*/

DECLARE
CURSOR CUR_DEPTOS IS
SELECT DEPARTMENT_ID, DEPARTMENT_NAME
FROM HR.DEPARTMENTS;
CURSOR CUR_EMP_DEPTO(DEPTNO NUMBER) IS
SELECT FIRST_NAME || ' ' || LAST_NAME NOMBRE_EMP
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID = DEPTNO;
V_TOTAL_EMP NUMBER(2);
BEGIN
DBMS_OUTPUT.PUT_LINE(' Empleados por Departamento');
DBMS_OUTPUT.PUT_LINE('===================================');
DBMS_OUTPUT.NEW_LINE();
FOR REG_DEPTOS IN CUR_DEPTOS LOOP
DBMS_OUTPUT.PUT_LINE('Departamento: '|| REG_DEPTOS.DEPARTMENT_NAME);
DBMS_OUTPUT.PUT_LINE('=====================================');
V_TOTAL_EMP := 0;
FOR REG_EMP_DEPTO IN CUR_EMP_DEPTO(REG_DEPTOS.DEPARTMENT_ID) LOOP
DBMS_OUTPUT.PUT_LINE(REG_EMP_DEPTO.NOMBRE_EMP);
V_TOTAL_EMP := V_TOTAL_EMP + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('=====================================');
DBMS_OUTPUT.PUT_LINE('Total de Empleados: ' || V_TOTAL_EMP);
DBMS_OUTPUT.NEW_LINE();
END LOOP;
END;

You might also like