MySQL聚合GROUP_CONCT和JSON_ARRAYAGG函数在存储过程中返回重复值



聚合函数适用于我的命令行和SQL客户端,但当我在存储过程中运行那些用于设置变量的聚合函数时,我会得到重复的值-多行的值数量相同,但所有值都相同。

Say I have a table `table_name`:
|test_field       | target_field|
|----------------:|:------------|
|"test_value"     |1            |
|"test_value"     |2            |
|"not_test_value" |3            |
|"test_value"     |4            |

聚合函数在常规SQL查询中按预期工作:

SET @array_value := "";
SELECT GROUP_CONCAT(target_field) INTO @array_value
FROM `table_name`
WHERE `test_field` = 'test_value';

我得到的结果是:"1,2,4";

然而,当我在存储过程中使用相同的语法时,我会得到非常不同的结果:"4,4,4〃;

请注意,此存储过程是在更新同一个表时触发的:

CREATE TRIGGER `cacheAggregate` 
AFTER INSERT ON `table_name` 
FOR EACH ROW 
BEGIN
CALL storedProcedureName (
NEW.target_field
);
END

它调用以下存储过程:

CREATE PROCEDURE `storedProcedureName `(
IN `target_field` VARCHAR
)
BEGIN
SET @answer_array := '';

SELECT GROUP_CONCAT(target_field) INTO @answer_array
FROM `table_name`
WHERE `test_field` = "test_value";

INSERT INTO CACHE_TABLE (`answers_array`, `fk_target_field`)
VALUES(@answer_array, target_field);
END

当我在表中插入一个值时,触发器会触发,调用存储过程,但问题本身就出现了——@answer_array是错误的,它由一个长度正确的数组组成,其中每个值总是输入到表中的最后一个值。

IE,如果我运行此查询:

INSERT INTO `table_name` (`test_field`,`target_field`) VALUES ("test_value", 5);

我希望它存储为:"1,2,4,5";

然而,实际返回的是:"5,5,5";

我的猜测是,存储过程使用了某种破坏聚合函数的游标/指针,但我很难找到有同样问题的人。

更新/解决

当我试图用修改后的示例代码重现这一点时,我发现了自己的问题。我把这个留在这里,以防将来对任何人都有帮助。

问题是命名冲突。我的存储过程的参数名称与表的target_field相同,因此SELECT语句使用的是存储过程参数,而不是表字段。由于传递给存储过程的值是触发器发送的最后一个更新值,因此它被复制为结果行的数量。

如果我在一个返回多行的select语句中使用了一个文字,这将是相同的,例如:

SELECT GROUP_CONCAT("String Literal") INTO @answer_array
FROM `table_name`
WHERE `test_field` = "test_value";

将产生以下结果:"字符串文本,字符串文本,字符文本,字符字符串">

解决方案是在GROUP_CONCT参数中显式设置表名:

SELECT GROUP_CONCAT(tn.target_field) INTO @answer_array
FROM `table_name` tn
WHERE `test_field` = "test_value";

-或-…您只需更改存储过程中传递的IN参数的名称:

CREATE PROCEDURE `storedProcedureName `(
IN `sp_target_field` VARCHAR
)
...

相关内容

  • 没有找到相关文章

最新更新