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/