> Manuales > Tutorial de Oracle

Continuamos con los cursores, esta vez vamos a ver atributos con cursores explícitos y uso de cursores para actualizar filas.

Atributos con Cursores implícitos

Los atributos de los cursores implícitos que se crean son los siguientes:
Es importante tener en cuenta una serie de cosas:

Si se trata de un select into tenemos que tener en cuenta que solo puede devolver una única fila de lo contrario nos levantará automáticamente una de estas dos excepciones:

  • NO_DATA_FOUND: si la consulta no devuelve ninguna fila
  • TOO_MANY_ROWS: si la consulta devuelve más de una fila
    Cuando un select into hace referencia a una función de grupo nuca se levantará la excepción NO_DATA_FOUND y SQL%FOUND siempre será verdadero. Esto se explica porque las funciones de grupo siempre devuelven algún valor (NULL se considera un valor).

    Uso de cursores para actualizar filas


    Para realizar una actualización con un cursor tenemos que añadir la siguiente FOR UPDATE al final de la declaración del cursor:

    CURSOR nombre_cursor <declaraciones> FOR UPDATE

    Esto indica que las filas seleccionadas por el cursor van a ser actualizadas o borradas. Una vez declarado un cursor FOR UPDATE, se incluirá el especificador CURRENT OF nombre_cursor en la cláusula WHERE para actualizar o borrar la última fila recuperada mediante la orden FETCH.

    {UPDATE|DELETE}... WHERE CURRENT OF nombre_cursor.

    Os pongo un ejemplo para que quede claro:

    Subir el salario a todos los empleados del departamento indicado en la llamada. El porcentaje se indicará también en la llamada.

    CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)
    IS
       CURSOR c IS SELECT oficio, salario FROM empleados WHERE    cod_dept=num_dept
       FOR UPDATE;
       reg c%ROWTYPE;
       inc NUMBER (8);
    BEGIN
       OPEN c;
       FETCH c INTO reg;
       WHILE c%FOUND LOOP
             inc :=(reg.salario/100 )* inc;
             UPDATE empleados SET salario=salario+inc WHERE CURRENT          OF c
             FETCH c INTO reg;
       END LOOP;
    END;

    También podemos usar ROWID en lugar de FOR UPDATE. ROWID nos indicará la fila que se va a actualizar. Para ello, al declarar el cursor en la cláusula SELECT indicaremos que seleccione también el identificador de fila:

    CURSOR nombre_cursor IS SELECT columna1,columna2,...ROWID FROM tabla;

    Al ejecutarse el FETCH se guardará el número de fila en una variable y después ese número se podrá usar en la cláusula WHERE de la actualización:

    {UPDATE |DELETE } ... WHERE ROWID = variable_rowid

    El ejemplo anterior utilizando ROWID quedaría de la siguiente manera:

    CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)
    IS
       CURSOR c IS SELECT oficio, salario,ROWID FROM empleados WHERE    cod_dept=num_dept
       FOR UPDATE;
       reg c%ROWTYPE;
       inc NUMBER (8);
    BEGIN
       OPEN c;
       FETCH c INTO reg;
       WHILE c%FOUND LOOP
             inc :=(reg.salario/100 )* inc;
             UPDATE empleados SET salario=salario+inc WHERE ROWID =          reg.ROWID;         
             FETCH c INTO reg;
       END LOOP;
    END;

    Con este artículo damos por terminado todo lo referente a cursores y empezamos a tratar las excepciones en el siguiente artículo.

  • Sara Alvarez

    Equipo DesarrolloWeb.com

    Manual