Eu vi duas abordagens diferentes de manipulação de cursor em procedimentos armazenados do MySQL. Agora estou curioso sobre a estabilidade deles, devido aos MYSQLEXCEPTION
riscos potenciais nas rotinas armazenadas.
Supondo que CURSOR
seja aberto quando o DBMS sobe MYSQLEXCEPTION
e vai para EXIT HANDLER
se for declarado...
Abordagem nº 1:
DELIMITER $$
CREATE PROCEDURE `test1`()
BEGIN
DECLARE `EOS` BOOLEAN DEFAULT FALSE;
DECLARE `buffer` INT UNSIGNED;
DECLARE `MyCursor` CURSOR FOR
SELECT
`id`
FROM
`MyTable`
LIMIT 50;
DECLARE EXIT HANDLER FOR MYSQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE 'ERR0R' SET MESSAGE_TEXT = 'Oops... FATAL ERROR!', MYSQL_ERRNO = 5656;
END;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET `EOS` = TRUE;
START TRANSACTION;
OPEN `MyCursor`;
cycle: LOOP
FETCH `MyCursor` INTO `buffer`;
IF `EOS`
THEN LEAVE cycle;
END IF;
-- INSERTs to another tables, UPDATEs of another tables and DELETEs from to another tables
-- Section that might throw a MYSQLEXCEPTION
END LOOP cycle;
CLOSE `MyCursor`;
COMMIT;
END$$
DELIMITER ;
Observe que, se MYSQLEXCEPTION
for lançado na seção comentada, MyCursor
provavelmente não será fechado. Ou será fechado e desalocado neste caso?
Em algum lugar eu vi seguindo...
Abordagem #2:
DELIMITER $$
CREATE PROCEDURE `test2`()
BEGIN
DECLARE `EOS` BOOLEAN DEFAULT FALSE;
DECLARE `buffer` INT UNSIGNED;
DECLARE `MyCursor` CURSOR FOR
SELECT
`id`
FROM
`MyTable`
LIMIT 50;
DECLARE EXIT HANDLER FOR MYSQLEXCEPTION
BEGIN
ROLLBACK;
CLOSE `MyCursor`; -- <---- is this even needed here ?
SIGNAL SQLSTATE 'ERR0R' SET MESSAGE_TEXT = 'Oops... FATAL ERROR!', MYSQL_ERRNO = 5858;
END;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET `EOS` = TRUE;
START TRANSACTION;
OPEN `MyCursor`;
cycle: LOOP
FETCH `MyCursor` INTO `buffer`;
IF `EOS`
THEN LEAVE cycle;
END IF;
-- INSERTs to another tables, UPDATEs of another tables and DELETEs from to another tables
-- Section that might throw a MYSQLEXCEPTION
END LOOP cycle;
CLOSE `MyCursor`;
COMMIT;
END$$
DELIMITER ;
E agora estou um pouco confuso sobre CURSOR
o manuseio.
Pergunta: Qual dessas abordagens é mais precisa e confiável? Se eu não estiver fechandoCURSOR
,EXIT HANDLER
isso afetará alguma coisa? E se for, quão " ruins " podem ser as consequências ?
use a Abordagem nº 1: de acordo com http://www.brainbell.com/tutorials/MySQL/Working_With_Cursors.htm
Se você não fechar explicitamente um cursor, o MySQL irá fechá-lo automaticamente quando a instrução END for alcançada.