Порядок выполнения в присвоении переменной SQL Server с использованием SELECT

В следующем примере:

declare @i int
select @i = 1, @i = 2
select @i

Будет ли @i всегда быть 2?

Это о самом тривиальном примере, о котором я могу думать, но я рассматриваю его использование для обмена значениями в переменных. Я также считаю, что этот метод присвоения (select) не является совместимым с ANSI (как бы он ни был полезен), но на самом деле не стоит иметь переносимый код в этом случае.

UPDATE

Благодаря @MichaelFredrickson у нас есть @MartinSmith ответ и ссылка на MSDN по этому вопросу. Я сейчас борюсь с тем, что означает второе предложение в этой документации, точно (выделено мной):

Если в одном выражении SELECT имеется несколько предложений предложения, SQL Server не гарантирует порядок оценки выражений. Обратите внимание, что эффекты видны только в том случае, если среди назначений есть ссылки.

Первое предложение достаточно для того, чтобы удержать меня от того, чтобы полагаться на поведение.

+7
14 февр. '13 в 20:58
источник поделиться
1 ответ

Для назначения переменной Мартин Смит отвечает на этот вопрос здесь, ссылаясь на MSDN:

Если в одной инструкции SELECT имеется несколько предложений предложения, SQL Server не гарантирует порядок оценки выражения. Обратите внимание, что эффекты видны только в том случае, если есть ссылки между назначениями.

Но...

Если мы имеем дело с таблицами, а не с переменными, это совсем другая история.

В этом случае Sql Server использует операцию All-At-Once, как описано Итцик Бен-Ган в Основах T-Sql.

В этой концепции указано, что все выражения в одной и той же логической фазе оцениваются как одна и та же точка во времени... независимо от их положения слева направо.

Поэтому при работе с соответствующим выражением UPDATE:

DECLARE @Test TABLE (
    i INT,
    j INT
)

INSERT INTO @Test VALUES (0, 0)

UPDATE @Test
SET
    i = i + 10,
    j = i

SELECT 
    i, 
    j 
FROM 
    @Test

Получаем следующие результаты:

i           j
----------- -----------
10          0   

И используя оценку All-At-Once... на Sql Server вы можете менять значения столбцов в таблице без промежуточной переменной/столбца.

Большинство RBDMS ведут себя так насколько мне известно, но MySql является исключением.


EDIT:

Обратите внимание, что эффекты видны только в том случае, если среди задания.

Я понимаю, это означает, что если у вас есть оператор SELECT, например:

SELECT
    @A = ColumnA,
    @B = ColumnB,
    @C = ColumnC
FROM MyTable

Тогда неважно, в каком порядке выполняются задания... вы получите те же результаты независимо от того, что. Но если у вас есть что-то вроде...

SELECT
    @A = ColumnA,
    @B = @A,
    @C = ColumnC
FROM MyTable

Теперь есть ссылка среди назначений (@B = @A), и теперь порядок, которому привязаны @A и @B, имеет значение.

+6
14 февр. '13 в 21:41
источник

Посмотрите другие вопросы по меткам или Задайте вопрос