【发布时间】:2021-12-31 05:39:04
【问题描述】:
我有一个 MySQL 存储过程(如下所示),它应该从分层相关记录表中构建一个 ID 列表。我不得不重新设计一个较旧的存储过程,从使用简单的 CONCAT 函数切换到 GROUP_CONCAT,因为前者无法处理正在生成的列表的大小(即,列表远远超过了 1024 个字符的限制CONCAT 函数)。
DELIMITER $$
CREATE PROCEDURE SPTest (top_id INT)
BEGIN
DECLARE ids_all TEXT;
SET SESSION group_concat_max_len = 1000000;
SET ids_all = top_id;
SET @str = GROUP_CONCAT('SELECT GROUP_CONCAT(id SEPARATOR \', \') ',
'FROM tbl WHERE nha_id = ', top_id, ' INTO @ids_tmp' SEPARATOR '');
PREPARE stmt FROM @str;
EXECUTE stmt;
WHILE @ids_tmp != "" DO
SET ids_all = GROUP_CONCAT(ids_all, @ids_tmp SEPARATOR ', ');
SET @str = GROUP_CONCAT('SELECT GROUP_CONCAT(id SEPARATOR \', \') ',
'FROM tbl WHERE nha_id IN (', @ids_tmp, ') INTO @ids_tmp' SEPARATOR '');
PREPARE stmt FROM @str;
EXECUTE stmt;
END WHILE;
SELECT ids_all AS ids;
END $$
DELIMITER ;
问题是这个例程在我尝试调用它时会产生以下错误(有时它会在我尝试创建存储过程时返回此错误):
ERROR 1111 (HY000): Invalid use of group function
当我手动创建与此代码相同类型的查询并在命令行中运行它们时,它们工作得非常好——没有任何类型的错误,而且我得到了我期望的结果。我已经看到帖子(在 Stack Exchange 和其他地方)说 MySQL 不支持嵌套聚合函数,但这里的连接只是对字符串进行。所以我认为它可能以某种方式在字符串中看到了GROUP_CONCAT 并因此而打嗝,所以我尝试在字符串中放入“XXXX”代替“GROUP_CONCAT”,然后使用REPLACE 函数将其切换回来,但这并没有什么区别。我还尝试使用WHERE 和HAVING 作为条件子句,但都没有奏效。我还进行了广泛的网络搜索,但找不到任何有用的东西。
我不知道还能尝试什么,主要是因为我看不出这里的语法有什么问题。任何帮助将不胜感激。
更新 1:
此后,我尝试了脚本的修改版本,其中GROUP_CONCAT 合并来自子查询的数据,如下所示:
SET @qrystr = GROUP_CONCAT('SELECT GROUP_CONCAT(c SEPARATOR ", ") ',
'FROM (SELECT id AS c FROM tbl WHERE nha_id IN (', @ids_tmp,
') AS d INTO @ids_tmp' SEPARATOR '');
但这也没什么区别。
【问题讨论】:
标签: mysql stored-procedures group-concat