【问题标题】:MySQL: Cursor doesn't seem to ever endMySQL:光标似乎永远不会结束
【发布时间】:2018-04-28 19:29:26
【问题描述】:

我正在使用 Aurora/MySQL。我有一个光标,它似乎永远不会完成/完成。

真正让我困惑的是我在网上看到的示例,我从未见过它们将“完成”或“完成”变量设置为 1。下面是我的脚本。

DELIMITER $$

DROP PROCEDURE IF EXISTS mass_backup $$

CREATE PROCEDURE mass_backup () 
    BEGIN
        DECLARE copy_table VARCHAR(255);
        DECLARE done BOOLEAN DEFAULT 0;
        DECLARE table_cursor CURSOR FOR
            SELECT table_name FROM information_schema.tables WHERE table_schema='app_prod_schema';
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

        OPEN table_cursor;

        REPEAT
            FETCH table_cursor INTO copy_table;
            SELECT copy_table;
            SET @var1 = copy_table;
            SET @copySql = CONCAT('SELECT * FROM ',@var1,' INTO OUTFILE S3 ''''s3://somebucket.com-work-bucket/''', @var1 , 
                    '.csv', 'FIELDS TERMINATED BY '','' LINES TERMINATED BY ''\n''' );
            SELECT @copySql;
        UNTIL done END REPEAT;
        CLOSE table_cursor;
    END $$

DELIMITER ;

CALL mass_backup()

这个光标到底为什么要永远运行?非常感谢任何帮助。

【问题讨论】:

  • 看起来您正在将每个表从特定模式导出到 CSV。只需检查目录是否存在文件,然后比较您有多少文件与架构中有多少表。
  • @lad2025 是的,这就是我想要做的。问题是只有大约 25 个表,但我看到 100 多个结果集选项卡。现在我只是想确保 '@'copySql 变量读起来像我认为应该读的那样。
  • What is really confusing me is in the examples I've seen online, I never see them set "done" or "finish" variable to one. => DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; /DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  • @lad2025 是的,我从我抓取的 copypasta 中看到了处理程序,我认为它类似于使 REPEAT 循环短路的异常处理程序。但它似乎永远不会被触发。
  • @lad2025 我想我解决了。在此过程中,我的 REPEAT 循环中的那些 SELECT 把事情搞砸了。或者也许不是这样,我不确定。

标签: mysql amazon-aurora database-cursor


【解决方案1】:

我认为我在重复循环中的 SELECT 正在搞乱“No more rows”处理程序。我删除了重复并放入一个循环。给我预期的陈述,这似乎很有魅力。

DELIMITER $$

DROP PROCEDURE IF EXISTS mass_backup $$

CREATE PROCEDURE mass_backup () 
    BEGIN
        DECLARE copy_table VARCHAR(255);
        DECLARE done BOOLEAN DEFAULT 0;
        DECLARE table_cursor CURSOR FOR
            SELECT table_name FROM information_schema.tables WHERE table_schema='app_prod_schema' ORDER BY table_name;
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

        DROP TEMPORARY TABLE IF EXISTS stmtsTable;
        CREATE TEMPORARY TABLE stmtsTable (backupStmt varchar(200));

        OPEN table_cursor;
        curloop:
        LOOP
            FETCH table_cursor INTO copy_table;
                IF done THEN
            LEAVE curloop;
            END IF;
            #SELECT copy_table;
            SET @var1 = copy_table;
            SET @copySql = CONCAT('SELECT * FROM ',@var1,' INTO OUTFILE S3 \'s3://somebucket/dbbackups/', @var1 , 
                    '.csv\'', ' FIELDS TERMINATED BY \',\' LINES TERMINATED BY \'\\n\'' );
            INSERT INTO stmtsTable(backupStmt)             
            SELECT @copySql;
        END LOOP;
        CLOSE table_cursor;
        SELECT * FROM stmtsTable;
END $$

【讨论】:

  • 对于任何想要深入了解细节的人来说,这里的关键是 continue 处理程序和 IF done THEN LEAVE curloop; END IF;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2013-04-09
  • 2010-12-27
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
相关资源
最近更新 更多