Escolar Documentos
Profissional Documentos
Cultura Documentos
Aprendizaje Esperado :
Construye unidades de programacin, segn sintaxis, restricciones del lenguaje,
requisitos de la lgica de negocios y de informacin.
Utiliza recursos del lenguaje segn su sintaxis, restricciones, requisitos de la
lgica de negocios y de informacin.
DECLARE
CURSOR cur_emp IS
SELECT ..
;
BEGIN
FOR reg_emp IN cur_emp LOOP
.;
END LOOP;
END;
Objetivos de la Clase
Filas Retornadas
Set Activo
Control de Cursores Explcitos
SI
NO
Filas
DECLARE OPEN FETCH
a leer?
CLOSE
Libera el
set activo
Control de Cursores Explcitos
Puntero del
cursor
3 Cierra el cursor.
Declarar el Cursor
Sintaxis:
CURSOR nombre_cursor IS
sentencia_select;
Ejemplos:
DECLARE DECLARE
CURSOR cur_emp IS v_locid NUMBER:= 1700;
SELECT employee_id, last_name CURSOR cur_dept IS
FROM employees SELECT *
WHERE department_id =30; FROM departments
WHERE location_id = v_locid;
Abrir el Cursor
Sintaxis:
OPEN nombre_cursor;
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM employees
WHERE department_id =30;
...
BEGIN
OPEN emp_cursor;
Obtener Datos del Cursor
Sintaxis:
FETCH nombre_cursor INTO lista_de_variables;
FETCH nombre_cursor INTO registro_PL/SQL;
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM employees
WHERE department_id =30;
v_lname employees.last_name%TYPE;
v_empno 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;
Obtener Datos del Cursor
Ejemplo:
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_empno employees.employee_id%TYPE;
v_lname 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
Sintaxis:
CLOSE nombre_cursor;
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM employees
WHERE department_id =30;
lname employees.last_name%TYPE;
empno 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 para Cursores Implcitos
Hay cuatro atributos para obtener informacin del estado de un cursor
explcito.
Ejemplo:
IF NOT cur_emp%ISOPEN THEN
OPEN cur_emp;
END IF;
LOOP
FETCH cur_emp ...
Atributos %ROWCOUNT y %NOTFOUND
El atributo de cursor %ROWCOUNT permite procesar un nmero
exacto de las filas. %ROWCOUNT y %NOTFOUND pueden ser
usados para condiciones de salida en un loop.
Ejemplo:
DECLARE
v_empleado VARCHAR2(60);
CURSOR cur_emp IS
SELECT first_name || ' ' || last_name
FROM 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
El atributo %ROWTYPE permite definir un registro basado en las
columnas seleccionadas en un cursor explcito.
Los valores de la fila leda desde el cursor se almacenan directamente
en los campos correspondientes del registro.
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM 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
Para poder iterar a travs del cursor se puede usar LOOP Simple.
Esto permite leer todas las filas (o una cantidad de filas determinadas)
del cursor de acuerdo a la condicin de salida del loop.
Sintaxis:
OPEN nombre_cursor;
LOOP
FETCH nombre_cursor INTO lista_variables | registro_PL/SQL;
EXIT WHEN nombre_cursor%NOTFOUND | EXIT WHEN nombre_cursor%ROWCOUNT;
/* Procesamiento de los registros recuperados y ejecucin de sentencias */
END LOOP;
CLOSE nombre_cursor;
Manejo del Cursor: Loop Simple
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM employees
WHERE department_id =30;
lname employees.last_name%TYPE;
empno 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
La instruccin FETCH aparece dos veces.
Para leer todas filas se utiliza WHILE LOOP.
Para validar que existan filas en el cursor se utiliza el atributo
%FOUND.
Sintaxis:
OPEN nombre_cursor;
FETCH nombre_cursor INTO lista_variables;
WHILE nombre_cursor%FOUND
LOOP
/* Procesamiento de los registros recuperados y ejecucin de sentencias*/
FETCH nombre_cursor INTO lista_variables;
END LOOP;
CLOSE nombre_cursor;
Manejo del Cursor: WHILE LOOP
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
empno employees.employee_id%TYPE;
lname 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
Es el mtodo ms fcil para procesar cursores explcitos ya que se
ejecutan implcitamente las instrucciones OPEN, FETCH, EXIT y
CLOSE
Sintaxis:
FOR nombre_registro IN nombre_cursor LOOP
/* Procesamiento de los registros recuperados y ejecucin de sentencias*/
END LOOP;
Manejo del Cursor: FOR LOOP
Ejemplo:
DECLARE
CURSOR cur_emp IS
SELECT employee_id, last_name
FROM 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;
Cursor FOR LOOP usando Subconsultas
No hay necesidad de declarar el cursor.
Ejemplo:
BEGIN
FOR emp_record IN (SELECT employee_id, last_name
FROM employees
WHERE department_id =30)
LOOP
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id ||' '||emp_record.last_name);
END LOOP;
END;
Cursores con Parmetros
Permite abrir y cerrar un cursor explcito muchas veces en un bloque
retornando un set activo diferente en cada ocasin.
Sintaxis:
OPEN nombre_cursor(valor_parmetro,.....) ;
Cursores con Parmetros
Ejemplo:
DECLARE
CURSOR emp_cursor (p_deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = p_deptno;
v_empno employees.employee_id%TYPE;
v_lname 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 FOR UPDATE
Bloquea en forma explcita las filas, antes de su actualizacin o
eliminacin, para no permitir el acceso a otras sesiones mientras se
realiza la transaccin.
Sintaxis:
CURSOR nombre_cursor
SELECT ...
FROM ...
FOR UPDATE [OF column_referenciada][NOWAIT | WAIT n];
Ejemplo:
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = 80 FOR UPDATE OF salary NOWAIT;
..
Clusula WHERE CURRENT
Se utiliza junto con la clusula FOR UPDATE para hacer referencia a
la fila actual de un cursor explcito.
Sintaxis:
BEGIN
{UPDATE|DELETE}... WHERE CURRENT OF nombre_cursor ;
Clusula WHERE CURRENT
Ejemplo:
DECLARE
empleado employees%ROWTYPE;
CURSOR emp_cursor IS
SELECT *
FROM 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 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
Una subconsulta es una consulta SQL que proporciona una valor o set
de valores para la consulta externa.
Ejemplo:
DECLARE
CURSOR mi_cursor IS
SELECT first_name || ' ' || last_name, salary
FROM employees
WHERE salary < (SELECT ROUND(AVG(salary))
FROM employees)
ORDER BY salary, last_name;
nombre VARCHAR2(50);
salario 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;
Cursores con Subconsultas
SALARIO PROMEDIO
...................
...................
Trabajando con ms de un Cursor
Ejemplo:
DECLARE
CURSOR cur_deptos IS
SELECT department_id, department_name
FROM departments;
CURSOR cur_emp_depto(deptno NUMBER) IS
SELECT first_name || ' ' || last_name nombre_emp
FROM 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;
Trabajando con ms de un Cursor
...................
...................
...................
...................
Resumen de la Clase
Se explicaron las diferencias entre cursores implcitos y explcitos.
Se explic cundo y por qu utilizar cursores explcitos
Se explic cmo declarar y controlar cursores explcitos
Se explic cmo Usar Loop Simple y FOR Loop para obtener los datos del
cursor explcito
Se explic cmo declarar y utilizar cursores con parmetros
Se explic el uso de la clusula FOR UPDATE para bloqueo de filas.
Se explic el uso de la clusula WHERE CURRENT OF para hacer
referencia a la fila actual del cursor explcito.
Se explic cmo trabajar con ms de un cursor explcito.