2017-10-18 93 views
0

下面的代码只循环一次游标,在一个循环中,它将product_name和list_price设置为null。我已经运行了SELECT语句(CURSOR的那个),它返回4个结果。我不确定如何或为何它在所有4次不循环,为什么,它的单回路,它是干什么的,是不是使用PRODUCT_NAME和list_price第一记录的值MySQL CURSOR没有获取所需的行

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(); 

回答

0

以下结束了速记答案。我有两个问题,首先在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 ; 
1

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

而且我们知道表达:

CONCAT(NULL,'something') 

评估为NULL。无论我们添加多少个非NULL值,它仍然是NULL。

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

SET retString = 'foo'; 

然后看看你得到了什么。我怀疑有一个空字符串开始将得到你所追求的:

SET retString = ''; 

这也可以被指定为DEFAULT的程序变量,而不是一个单独的SET声明。

如果CONCAT函数中的参数的任何评估为NULL,则CONCAT将返回NULL。 (考虑当product_namelist_price为NULL会发生什么。)MySQL有用于测试NULL值,否则返回东西一个方便的功能...

IFNULL(foo,'bar') 

IF(foo IS NULL,'bar',foo)