web-dev-qa-db-ja.com

ストアドプロシージャで例外が発生した場合、MySQLはカーソルを閉じますか?

カーソル処理の2つの異なるアプローチはMySQLストアドプロシージャです。ストアドルーチンに潜在的なMYSQLEXCEPTIONリスクがあるため、これらの安定性に興味があります。

仮定すると、DBMSがCURSORを発生させ、宣言されている場合はEXIT HANDLERに移動すると、MYSQLEXCEPTIONが開かれます...

アプローチ#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 ;

コメントされたセクションでMYSQLEXCEPTIONがスローされる場合、MyCursorはおそらく閉じられないことに注意してください。 それとも、この場合、閉じられて割り当てが解除されますか?

以下のどこかで見たことがあります...

アプローチ#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 ;

そして今、私はCURSORの取り扱いについて少し混乱しています。

質問:このアプローチのうち、より正確で信頼できるのはどれですか? EXIT HANDLERCURSORを閉じない場合、何か影響がありますか?そして、もしそうなら、どのように "bad"が結果であるか

2
BlitZ

http://www.brainbell.com/tutorials/MySQL/Working_With_Cursors.htm に従ってアプローチ#1:を使用します

カーソルを明示的に閉じない場合、MySQLはENDステートメントに到達したときに自動的にカーソルを閉じます。

2
user3693690