lunes, 26 de agosto de 2013

viernes, 2 de agosto de 2013

Uso basico de un cursor. MYSQL.

 Esquema basico manejo cursores en MYSQL

 

    DECLARE idone INT DEFAULT 0; /* Incluir aqui Todas las variables del cursor*/ DECLARE docs CURSOR FOR /* añadir aqui la sentencia SQL */ ; DECLARE CONTINUE HANDLER FOR NOT FOUND SET idone = 1; OPEN docs; REPEAT FETCH docs INTO /* asignacion valores cursor a variables */ ; IF NOT idone THEN /* INCLUIR AQUI TODO EL CODIGO PARA CADA REGISTRO DEL CURSOR */ END IF; UNTIL idone END REPEAT; CLOSE docs;
Fuente: http://snipplr.com/view/25659/

Procedimiento MYSQL con un cursor.

Procedimiento definido en  MYSQL con un cursor.

Primero es mejor orientarse desde un código ya publicado (en foros, blog o paginas de ayduda de MYSQL) muchas veces ayuda a indicar los errores principales.

Tips básicos:
1) Necesitas un HANDLER para el SQLSTATE '02000' para que MySQL determine el cierre de la lectura cuando llegue al último registro. Si no lo usas se generará un error cuando el cursor intente avanzar más allá de eso.

2) Necesitarás una variable que uses de flag para indicar que salga de la lectura. Se usa en combinación con el HANDLER, haciendo que este cambie el estado del flag.

3) Todas las variables locales se declaran todas al principio. No se puede declarar variables luego de declarar el HANDLER, ni siquiera cursores.

4) No puedes actualizar la(s) tabla(s) que lee el cursor, porque al momento de recorrerla(s) tiene(n) un bloqueo de lectura/escritura, producto del trazado del cursor. Obviamente el proceso tiene que ser planeado de modo que eso no impida el UPDATE que quieres hacer.


Ejemplo del caso:
(De http://fernandoguillen.info/2008/04/08/procedimiento-almacenado-con-cursor-en-mysql/)

CREATE procedure test_cursor()
begin

-- variables
declare hasMoreRows bool DEFAULT true;
declare _field1 varchar(20);
declare _field2 varchar(20);
 
--
-- the cursor
--
declare cur cursor FOR
  SELECT  cl.LIBRARY_NAME, cl.LIBRARY_DESCRIPTION
  FROM CAT_LIBRARIES AS cl;
 
 declare continue handler FOR SQLSTATE '02000'
    SET hasMoreRows = false;
 
--
-- create table test
--
CREATE TABLE `test_cursor` (
  `field1`  varchar(20) NULL,
  `field2`  varchar(20) NULL
);
 
--
-- open the cursor
--
open cur;
 
fetch cur INTO
  _field1,
  _field2;
 
while hasMoreRows do
 
--
-- ####### WALK:INI ########
--
  INSERT INTO
      test_cursor
  SET
    field1 = _field1,
    field2 = _field2
  ;
 
--
-- ####### WALK:END ########
--
  fetch cur INTO
    _field1,
    _field2;
 
end while;

close cur;
 
end;
/


Fuentes: http://www.forosdelweb.com/f86/procedimiento-almacenado-mysql-con-cursor-918568/
http://fernandoguillen.info/2008/04/08/procedimiento-almacenado-con-cursor-en-mysql/