这个问题在这里已有答案:
我在MS SQL Server 2017中观察到了一些奇怪的行为。
+=
充当聚合器('连接所有行的值')。+=
在右侧是列名称时仅用作“设置值”。 (另外,这会改变其他列的聚合行为)所以我的问题是:
@c1
结果只包含最后一行的值,即使使用+=
?@c2
受到+=
的变化=
-> @c1
的影响?BEGIN
DECLARE
@c1 NVARCHAR(MAX) = N'',
@c2 NVARCHAR(MAX) = N'';
SELECT
@c1 = constraint_name, -- version-1
@c2 += '+'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
ORDER BY 1 DESC
;
PRINT '@c1=' + @c1;
PRINT '@c2=' + @c2;
END
;
版本1结果:
@c1 = fk_abcde
@c2 = ++++++++++++++++++++++++++++++++++++++++++
(`@c2` result is aggregation of many rows; one plus for each row)
BEGIN
DECLARE
@c1 NVARCHAR(MAX) = N'',
@c2 NVARCHAR(MAX) = N'';
SELECT
@c1 += constraint_name, -- version-2
@c2 += '+'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
ORDER BY 1 DESC
;
PRINT '@c1=' + @c1;
PRINT '@c2=' + @c2;
END
;
版本2结果:
@c1 = fk_abcde
@c2 = +
(`@c2` is just value assigned from last processed row)
这感觉很奇怪 - 有点像虫子。我没有找到任何关于此的文档。 doc on '+= string'根本没有在+=
查询中提及select
用法。
(目前我的目标是完全理解这种行为,所以我不会不小心踩到它。任何提示正确的文档/关键字搜索都会有所帮助)
这是在wrong place in the documentation,所以你没有找到它并不奇怪:
不要在SELECT语句中使用变量来连接值(即,计算聚合值)。可能会发生意外的查询结果。因为,SELECT列表中的所有表达式(包括赋值)不一定只为每个输出行运行一次
最好寻找不同的字符串连接方式。如果您的版本支持它,请选择使用STRING_AGG
。对于早期版本,Aaron Bertrand提供了good set of options(帽子提示给Panagiotis Kanavos for providing the link)
好吧,我发现非常有趣:没有ORDER BY
查询一致和预期运行。
但是当添加qazxsw poi子句时,我会得到与你相同的结果。
我建议使用CTE和排序 - 遗憾的是CTE或子查询中不允许排序,但解决方法是使用ORDER BY
关键字,这允许我们在这种情况下订购。
见下面的脚本:
TOP
您应该使用;with cte as (
select top 100 percent table_schema
from information_schema.columns
order by 1
)
-- This is more reliable
select @c1 = table_schema, @c2 += '+' from cte
而不是Order by constraint_name
,因为您将值分配给变量。它不是选择声明。