首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么这个MySQL函数返回null?

为什么这个MySQL函数返回null?
EN

Stack Overflow用户
提问于 2009-05-27 17:44:03
回答 4查看 9.5K关注 0票数 1

描述:实际运行的查询返回了4个结果,从下面可以看到,我所做的只是连接这些项然后返回,但出乎意料的是,它是空的。

我认为代码是不言自明的:

代码语言:javascript
代码运行次数:0
运行
复制
DELIMITER |

DROP FUNCTION IF EXISTS get_idiscussion_ask|

CREATE FUNCTION get_idiscussion_ask(iask_id INT UNSIGNED) RETURNS TEXT DETERMINISTIC
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE body varchar(600);
  DECLARE created DATETIME;
  DECLARE anonymous TINYINT(1);
  DECLARE screen_name varchar(64);
  DECLARE result TEXT;
  DECLARE cur1 CURSOR FOR SELECT body,created,anonymous,screen_name from idiscussion left join users on idiscussion.uid=users.id where idiscussion.iask_id=iask_id;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  SET result = '';
  OPEN cur1;
  REPEAT
    FETCH cur1 INTO body, created, anonymous, screen_name;
    SET result = CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>');
  UNTIL done END REPEAT;
  CLOSE cur1;

  RETURN result;
END |

DELIMITER ;

mysql> DELIMITER ;
mysql> select get_idiscussion_ask(1);
+------------------------+
| get_idiscussion_ask(1) |
+------------------------+
| NULL                   |
+------------------------+
1 row in set (0.01 sec)



mysql> SELECT body,created,anonymous,screen_name from idiscussion left join users on idiscussion.uid=users.id where idiscussion.iask_id=1;
+------+---------------------+-----------+-------------+
| body | created             | anonymous | screen_name |
+------+---------------------+-----------+-------------+
| haha | 2009-05-27 04:57:51 |         0 | NULL        |
| haha | 2009-05-27 04:57:52 |         0 | NULL        |
| haha | 2009-05-27 04:57:52 |         0 | NULL        |
| haha | 2009-05-27 04:57:53 |         0 | NULL        |
+------+---------------------+-----------+-------------+
4 rows in set (0.00 sec)

对于那些不认为代码是不言自明的人:

函数为什么返回NULL**?**

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-05-27 17:50:51

将变量和输入参数重命名,它们是不明确的。

此查询:

代码语言:javascript
代码运行次数:0
运行
复制
SELECT  body, created, anonymous, screen_name
FROM    idiscussion
LEFT JOIN
        users
ON      idiscussion.uid = users.id
WHERE   idiscussion.iask_id = iask_id

返回以前声明的变量(即NULL),而不是表列。

用下划线准备变量名和输入参数名。

另外,你还会做一项额外的任务来完成:

代码语言:javascript
代码运行次数:0
运行
复制
FETCH cur1 INTO body, created, anonymous, screen_name;
SET result = CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>');

处理程序在done失败后设置FETCH,但仍然分配result

将处理程序更改为:

代码语言:javascript
代码运行次数:0
运行
复制
DECLARE EXIT HANDLER FOR SQLSTATE '02000' RETURN result;

最后:在MySQL中,这可以通过一个查询来完成。没有必要用函数来完成它。

代码语言:javascript
代码运行次数:0
运行
复制
SELECT  GROUP_CONCAT(CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>') SEPARATOR '')
FROM   idiscussion
LEFT JOIN
       users
ON     idiscussion.uid=users.id
WHERE  idiscussion.iask_id = @_iask_id
票数 3
EN

Stack Overflow用户

发布于 2009-05-27 18:39:01

请记住,将任何字符串与NULL连接在一起返回NULL。试试这个测试:

代码语言:javascript
代码运行次数:0
运行
复制
mysql> SET @s = 'test string';
mysql> SET @s = CONCAT(@s, '<tag>', NULL, '</tag>');
mysql> SELECT @s;

这将返回NULL。

因此,当您遍历游标时,如果bodycreated列在任何行上为NULL,则result变为NULL。然后,在循环的后续迭代中,与空result连接的任何东西都没有效果;它仍然是空的。

试着做这样的事情:

代码语言:javascript
代码运行次数:0
运行
复制
REPEAT
    FETCH cur1 INTO body, created, anonymous, screen_name;
    SET result = CONCAT(result, 
      '<comment><body><![CDATA[', 
      COALESCE(body, ''),
      ']]></body>', 
      '<replier>', 
      IF(COALESCE(anonymous, 0) != 0, COALESCE(screen_name, ''), ''), 
      '</replier>',
      '<created>',
      COALESCE(created, ''),
      '</created></comment>'
    );
UNTIL done END REPEAT;

COALESCE()函数在标准SQL中是一个有用的函数。它返回第一个非空参数。

票数 1
EN

Stack Overflow用户

发布于 2009-08-26 23:10:33

CONCAT_WS(分离器,str1,str2,.)CONCAT_WS()表示与分离器连接,是一种特殊形式的CONCAT()。第一个参数是其余参数的分隔符。分隔符在要连接的字符串之间添加:分隔符可以是字符串,其余的参数也可以是字符串。如果分隔符为空,则结果为空。函数在分隔符参数之后跳过任何空值。

mysql>

代码语言:javascript
代码运行次数:0
运行
复制
SELECT CONCAT_WS(",","First name","Second name","Last Name");
   -> 'First name,Second name,Last Name'

mysql>

代码语言:javascript
代码运行次数:0
运行
复制
SELECT CONCAT_WS(",","First name",NULL,"Last Name");
   -> 'First name,Last Name'

在MySQL 4.0.14之前,CONCAT_WS()跳过空字符串和空值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/917091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档