2 Pl SQL Cursores Oracle 11g

download 2 Pl SQL Cursores Oracle 11g

of 13

description

Cursores en Oracle 11g

Transcript of 2 Pl SQL Cursores Oracle 11g

  • PL/SQL EN ORACLE

    PL / SQLCURSORES

  • CURSORES

    Si una sentencia SELECT devuelve ms de una fila*,se debe usar un cursor para su procesamiento enPL/SQL.

    Para declarar y usar un cursor se siguen estos pasos:

    1. Declarar el cursor: Se le asigna un nombre alcursor y se le asocia una consulta

    2. Abrir el cursor: Se ejecuta la consulta; en esemomento se est apuntando a la primera de las filasseleccionadas por la consulta

    3. Recuperar, tomar las filas del cursor una a una

    4. Cerrar el cursor: Liberar la memoria

    Proceso

    iterativo

    * Los cursores funcionan para cualquier consulta ya sea que esta

    devuelva 0, 1 o muchas filas

  • CURSOR

    Sintaxis:

    CURSOR nombre_cursor -- Se declaraIS consulta SQL;

    OPEN nombre_cursor; -- Se abreFETCH nombre_cursorINTO 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 ejecutadorecuper datos (trajo una fila)

    %ROWCOUNT: Devuelve el nmero de filas ledas hasta elmomento

    %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, nihacerles 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

  • CURSOR SIN DECLARAR

    Se puede tambin evitar la declaracin de un cursoras:

    BEGIN

    FOR mi_e IN (SELECT codigo, dep

    FROM empleado ORDER BY dep)

    LOOP

    DBMS_OUTPUT.PUT_LINE(mi_e.codigo || ' - ' || mi_e.dep);

    END LOOP;

    END;

    /

  • CURSOR CON PARAMETRO

    SET SERVEROUTPUT ON

    DECLARE

    total NUMBER(5); grantotal NUMBER(6) := 0;

    CURSOR emp_cur(v_dept NUMBER) IS

    SELECT nombre FROM empleado WHERE dep = v_dept;

    BEGIN

    FOR k IN 1..5 LOOP

    DBMS_OUTPUT.PUT_LINE('Dpto ' || k);

    total := 0;

    FOR mi_e IN emp_cur(k) LOOP

    DBMS_OUTPUT.PUT_LINE('Empleado: '|| mi_e.nombre);

    total := total + 1;

    END LOOP;

    DBMS_OUTPUT.PUT_LINE('Total empleados en el dpto: ' || total);

    grantotal := grantotal + total;

    END LOOP;

    DBMS_OUTPUT.PUT_LINE('Total empleados en la empresa: ' || grantotal);

    END;

    /

  • 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;

    LOOP

    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;

    /

    Todos los datos de un

    empleado quedan almacenados

    en mi_e

  • Tambin se pueden declarar variables del tipo de un cursor:

    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?

  • FOR UPDATE y CURRENT OF

    DECLARE

    CURSOR emp_c IS SELECT dep FROM empleado FOR UPDATE;

    BEGIN

    FOR mi_e IN emp_c

    LOOP

    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

    WHERE CURRENT OF emp_c;

    END IF;

    END LOOP;

    END;

    /

    FOR UPDATE bloquea las filas ledas por el cursor antes* de hacer el UPDATE o

    el DELETE

    Al abrir, el cursor toma

    una imagen de las filas

    y las bloquea

    * Si no hay FOR UPDATE, Oracle bloquea las filas en el momento de hacer el

    UPDATE o el DELETE. FOR UPDATE establece el bloqueo desde el OPEN.

    Para usar CURRENT OF el cursor debe ser FOR UPDATE.