聚合函数适用于我的命令行和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
)
...