我遇到过一些似乎依赖于我发现意外行为的 T-SQL 代码。
在一个 SELECT 语句中为多个 @variables 赋值时,当一个 @variables 依赖于另一个时,@variables 在语句中出现的顺序会改变结果。
例如:-
DECLARE @a INT;
DECLARE @b INT;
SET @a = 0;
SET @b = 0;
SELECT @a = 3,
@b = 5 - @a;
SELECT '@a before @b' AS Test,
@a AS [Value Of @a],
@b AS [Value Of @b];
SET @a = 0;
SET @b = 0;
SELECT @b = 5 - @a,
@a = 3;
SELECT '@b before @a' AS Test,
@a AS [Value Of @a],
@b AS [Value Of @b];
测试 | @a 的值 | @b 的值 |
---|---|---|
@a 在@b 之前 | 3个 | 2个 |
我的期望是 @b 应该等于 5(而不是 2)——就像交换分配顺序时一样。
测试 | @a 的值 | @b 的值 |
---|---|---|
@b 在@a 之前 | 3个 | 5个 |
微软说:-“对于分配变量,我们建议您使用 SET @local_variable 而不是 SELECT @local_variable。 ”
但这并未提及原因,也未提及此行为是否是该建议背后的原因之一。
我可以轻松地将单个 SELECT 赋值转换为多个 SET 赋值,所以这不是什么大问题。
这不是使用依赖于另一个的值更新一个表列时的行为,例如:-
DECLARE @Table TABLE
(
[a] INT,
[b] INT
);
INSERT INTO @Table
(
[a],
[b]
)
VALUES
(0, 0);
UPDATE @Table
SET [a] = 3,
[b] = 5 - [a];
SELECT [a],
[b]
FROM @Table;
一个 | b |
---|---|
3个 | 5个 |
正如预期的那样,[b] 列是根据UPDATE之前的 [a] 列的值更新的——而不是 UPDATE 中分配给 [a] 列的值。
我的问题是有没有人知道这种行为是否有名称,所以我可以在代码审查中引用它(比“在单个 SELECT 语句中为多个变量赋值时,因变量赋值取决于赋值顺序”更有说服力) ?
这种行为几乎让人联想到古怪的更新。
是的。变量文档中提到了以下内容:
简而言之,正如您所注意到的,这只是 SQL Server 的设计方式不受支持的行为,并且可能导致意外行为。
我不这么认为,但我只是将其称为“ SELECT 语句中的多变量赋值”。