过程中的光标不返回任何值

时间:2015-05-07 08:14:26

标签: mysql loops cursor procedure

我有一个创建临时表的数据库,这些表名是随机生成的并保存在Checkouts.unid中。我想删除所有这些表并截断表Checkouts。我认为最麻烦的解决方案是一个程序,但它不起作用:

DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
  SQL SECURITY INVOKER
BEGIN
    DECLARE `t` VARCHAR(64);
    DECLARE `ch` CURSOR FOR SELECT `unid` FROM `Checkouts`;
    OPEN `ch`;

    drop_tables: LOOP
        FETCH `ch` INTO `t`;
        DROP TABLE IF EXISTS `t`;
    END LOOP;

    CLOSE `ch`;
    TRUNCATE TABLE `Checkouts`;
END

我总是得到"没有数据 - 提取,选择或处理零行#34;虽然这些表在那里,但表格Checkouts不是空的。

2 个答案:

答案 0 :(得分:0)

你必须添加这样的东西才能结束你的循环:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET ...;

参见documentation.中的示例。例如。 ...

DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
  SQL SECURITY INVOKER
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE `t` VARCHAR(64);
    DECLARE `ch` CURSOR FOR SELECT `unid` FROM `Checkouts`;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN `ch`;

    drop_tables: LOOP
        FETCH `ch` INTO `t`;
        IF done THEN
           LEAVE drop_tables;
        END IF;
        DROP TABLE IF EXISTS `t`;
    END LOOP;

    CLOSE `ch`;
    TRUNCATE TABLE `Checkouts`;
END

否则,一旦到达光标的末尾,就会出现错误。

答案 1 :(得分:0)

我得到了它的工作:

DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
  SQL SECURITY INVOKER
BEGIN
    DECLARE done int DEFAULT 0;
    DECLARE t CHAR(64);
    DECLARE ch CURSOR FOR SELECT `unid` FROM `Checkouts`;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN ch;

    drop_table: LOOP
        FETCH ch INTO t;
        IF done = 1 THEN
            LEAVE drop_table;
        END IF;
        SET @sql := CONCAT('DROP TABLE IF EXISTS `', t, '`'); 
        PREPARE dropt FROM @sql; 
        EXECUTE dropt;
    END LOOP;

    CLOSE ch;
    TRUNCATE TABLE `Checkouts`;
END;
CALL spCheckoutsCleanup;