Cursores PL/SQL tercera parte

07 de septiembre de 2009
Valoración del artículo:
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:
  • SQL%NOTFOUND: nos dice si el último insert, update,delete o select into no han afectado a ninguna fila.
  • SQL%FOUND: nos dice si el último insert, update,delete o select into ha afectado a una o mas filas
  • SQL%ROWCOUNT: devuelve el número de filas afectadas por el último insert, update, delete o select into
  • SQL%ISOPEN: Nos dice si el cursor esta cerrado, por lo que en teoría siempre nos dará falso ya que Oracle cierra automáticamente el cursor después de cada orden SQL.

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.

  • Comentarios
    Fueron enviados 3 comentarios al artículo
    2 comentarios no revisados
    1 comentario revisado:

    NarutoK...
    Como copiar a un cursor datos de otro cursor
    10/12/2012
    Hola buenas, les comento que tengo un pequeño problema al que espero me puedan ayudar a dar solución, resulta que tengo un cursor que lleno con una X query la cual obtiene datos de X n° de tablas y me genera X registros los cuales quedan almacenados en el cursor, luego recorro e itero este cursor para poder limpiar uno de los campos, finalmente hago un if donde separo los que me sirven y los que no, aquí es donde se presenta mi problema, ya que requiero dejar los registros que me sirven en otro cursor y lo que no, me da = que pase con ellos.

    Buscando en la web no logre encontrar solución a esto, por lo que agradecería su pronta ayuda. gracias!

    Manuales relacionados
    Categorias relacionadas
    El autor
    Sara Alvarez
    Equipo DesarrolloWeb.com
    http://www.desarrolloweb.com


    Últimas noticias
    Donaciones
    Si piensas que te hemos ayudado y merecemos tu apoyo económico...