为什么游标在一次迭代后退出?

Why is the cursor exiting after one iteration?

我有一个 table,其中列出了 table 个我想要计算的数:

|dq_tbl_id|dq_tbl_tbl_name           |dq_tbl_use_batch_stamp|
|---------|--------------------------|----------------------|
|1        |dev_credly_badges         |1                     |
|...      |...                       |...                   |
|18       |tbl18                     |[NULL]                |

我不明白为什么程序在一次迭代后退出:

CREATE DEFINER=`channel`@`%` PROCEDURE `dq_job_dev_count`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE proc_dq_tbl_id SMALLINT;
DECLARE tbl_count INT DEFAULT 0;
DECLARE tbl_name VARCHAR(35);
DECLARE dq_tbl_use_batch_stamp BOOL DEFAULT FALSE;

DECLARE dq_tbl_ids 
    CURSOR FOR 
        SELECT dq_tbl_id FROM ref_dq_tbl_count;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN dq_tbl_ids;   

WHILE done = 0 DO
    FETCH NEXT FROM dq_tbl_ids INTO proc_dq_tbl_id;

    IF done = 0 THEN
        SELECT dq_tbl_tbl_name, dq_tbl_use_batch_stamp INTO @tbl_name, @dq_tbl_use_batch_stamp FROM ref_dq_tbl_count WHERE dq_tbl_id = @proc_dq_tbl_id;

        IF @dq_tbl_use_batch_stamp = 1 THEN
            SET @sql_stmt = CONCAT('SELECT COUNT(*) INTO @tbl_count FROM ', @tbl_name, ' WHERE DATE(batch_stamp) = CURDATE()');
        ELSE
            SET @sql_stmt = CONCAT('SELECT COUNT(*) INTO @tbl_count FROM ', @tbl_name);
        END IF;

        PREPARE stmt FROM @sql_stmt;
        EXECUTE stmt;

        INSERT INTO prod_dq_tbl_load_counts (tbl_name, row_count) VALUES (@tbl_name, @tbl_count);
    END IF;
END WHILE;

CLOSE dq_tbl_ids;

END

您正在将游标结果提取到局部变量中:

FETCH NEXT FROM dq_tbl_ids INTO proc_dq_tbl_id;

随后您使用了 user-defined 变量 @proc_dq_tbl_id,错误地认为它包含您获取的值。

在 MySQL 存储过程中,具有 @ 标记的变量是您使用 DECLARE 创建的 user-defined variable. It is literally a different variable than the local variable

您可以将游标提取到 user-defined 变量中(使用 @ 标记),或者您可以将游标提取到局部变量中。但随后您必须在后续表达式中使用相同的变量。

由于 @proc_dq_tbl_id 可能为 NULL,因此您在其中使用它的 SELECT 语句将永远不会匹配任何行。您的光标可能循环了很多,但每个循环迭代中的 SELECT 语句都找不到匹配项。

MySQL 中对变量的这种处理不同于其他品牌的 SQL 数据库(例如 Microsoft SQL 服务器)。习惯使用其他品牌的开发人员有时会感到困惑。