Encontrei algum código T-SQL que parece depender de um comportamento que achei inesperado.
Ao atribuir valores a várias @variáveis em uma instrução SELECT, quando uma @variável depende de outra, a ordem na qual as @variáveis aparecem na instrução altera o resultado.
Por exemplo:-
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];
Teste | Valor de @a | Valor de @b |
---|---|---|
@a antes de @b | 3 | 2 |
Minha expectativa era que @b fosse igual a 5 (não 2) - como acontece quando a ordem de atribuição é trocada.
Teste | Valor de @a | Valor de @b |
---|---|---|
@b antes de @a | 3 | 5 |
A Microsoft diz :- " Para atribuir variáveis, recomendamos que você use SET @local_variable em vez de SELECT @local_variable. "
Mas isso não menciona o motivo ou se esse comportamento é um dos motivos por trás dessa recomendação.
Posso converter facilmente uma única atribuição SELECT em várias atribuições SET, portanto, não é um grande problema.
Este não é o comportamento ao atualizar uma coluna da tabela com um valor dependente de outro, por exemplo:-
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;
a | b |
---|---|
3 | 5 |
Como esperado, a coluna [b] é atualizada com base no valor da coluna [a] antes do UPDATE - não no valor atribuído à coluna [a] dentro do UPDATE.
Minha pergunta é: alguém sabe se existe um nome para esse comportamento para que eu possa me referir a ele em revisões de código (algo mais eloquente do que " valor de atribuição de variável dependente depende da ordem de atribuição ao atribuir valores a várias variáveis em uma única instrução SELECT ") ?
O comportamento quase lembra uma atualização peculiar .
É sim. O seguinte é mencionado nos documentos sobre variáveis :
Resumindo, é apenas um comportamento não compatível com a forma como o SQL Server foi projetado e pode levar a um comportamento inesperado, como você notou.
Acho que não oficialmente, mas apenas me referiria a isso como " atribuição de variável múltipla em uma instrução SELECT ".