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_name
或 list_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 ;
下面的代码只循环游标一次,在那个循环中,它将 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_name
或 list_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 ;