MySQL CURSOR 未获取所需的行

MySQL CURSOR not fetching desired rows

下面的代码只循环游标一次,在那个循环中,它将 product_name 和 list_price 设置为空。我有 运行 那个 SELECT 语句(CURSOR 语句)本身,它有 returns 4 个结果。我不确定它如何或为什么不循环所有 4 次,以及为什么在它正在执行的单个循环中没有使用 product_name 和 list_price

的第一个记录值
DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test()
BEGIN
    DECLARE retString VARCHAR(1000);
    DECLARE rowNotFound TINYINT DEFAULT FALSE;
    DECLARE product_name VARCHAR(255);
    DECLARE list_price DECIMAL(10,2);

    DECLARE prodCursor CURSOR FOR 
        SELECT product_name, list_price FROM products WHERE list_price > 700 ORDER BY list_price DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND 
        SET rowNotFound = TRUE;

    OPEN prodCursor;

    WHILE rowNotFound = FALSE DO
        FETCH prodCursor INTO product_name, list_price;
        SET retString = CONCAT(retString, '"', product_name, '","' , list_price, '"|');
    END WHILE;

    CLOSE prodCursor;

    SELECT retString AS 'Message';
END//
DELIMITER ;

CALL test();

我认为问题是 retString 被初始化为 NULL

我们知道表达式:

  CONCAT(NULL,'something') 

计算结果为 NULL。无论我们添加多少非 NULL 值,它仍然是 NULL。

尝试在循环之前将 retString 初始化为非 NULL 值。

  SET retString = 'foo';

看看你得到了什么。我怀疑以空字符串开头会得到你想要的东西:

  SET retString = '';   

这也可以指定为过程变量的 DEFAULT,而不是单独的 SET 语句。

如果 CONCAT 函数中的 任何 个参数的计算结果为 NULL,则 CONCAT 将 return NULL。 (考虑当 product_namelist_price 为 NULL 时会发生什么。)MySQL 有一个方便的函数来测试 NULL 值和 returning 其他东西...

 IFNULL(foo,'bar') 

是 shorthand 对于 IF(foo IS NULL,'bar',foo)

以下是答案。我有两个问题,首先需要更好地量化 SELECT 语句中的比较,并且(正如@spencer7593 指出的那样)retString 被初始化为 null。

DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test()
BEGIN
    DECLARE retString VARCHAR(1000);
    DECLARE rowNotFound TINYINT DEFAULT FALSE;
    DECLARE product_name VARCHAR(255);
    DECLARE list_price DECIMAL(10,2);

    DECLARE prodCursor CURSOR FOR 
        SELECT p.product_name, p.list_price FROM products p WHERE p.list_price > 700.00 ORDER BY p.list_price DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND 
        SET rowNotFound = TRUE;

    SET retString = '';
    OPEN prodCursor;

    WHILE rowNotFound = FALSE DO
        FETCH prodCursor INTO product_name, list_price;
        SET retString = CONCAT(retString, '"', product_name, '","' , list_price, '"|');
    END WHILE;

    CLOSE prodCursor;

    SELECT retString AS 'Message';
END//
DELIMITER ;