8

次の例を考えます。

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

@i常に2になりますか?

これは私が考えることができる最も些細な例ですが、変数の値を交換するためにこれを使用することを検討しています。また、この割り当て方法 (選択) は ANSI に準拠していないと思いますが (便利ではありますが)、この場合、移植可能なコードを用意する必要はありません。

アップデート

@MichaelFredrickson のおかげで、@MartinSmith の回答とこれに関するMSDNへの参照があります。このドキュメントの2番目の文が正確に何を意味するのか、私は今苦労しています(強調を追加):

1 つの SELECT ステートメントに複数の代入句がある場合、SQL Server は式の評価順序を保証しません。効果は、割り当て間に参照がある場合にのみ表示されることに注意してください。

ただし、最初の文は、動作に依存することを避けるのに十分です。

4

1 に答える 1

6

変数の割り当てについては、 Martin Smith がMSDNを参照してこの質問に回答しています。

1 つの SELECT ステートメントに複数の代入句がある場合、SQL Server は式の評価順序を保証しません。効果は、割り当て間に参照がある場合にのみ表示されることに注意してください。

しかし...

変数ではなくテーブルを扱っている場合は、話は別です。

この場合、T-Sql Fundamentals で Itzik Ben-Gan が説明しているように、Sql Server はAll-At-Once操作を使用します。

この概念は、同じ論理フェーズ内のすべての式が、左から右の位置に関係なく、同じ時点であるかのように評価されることを示しています。

したがって、対応する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   

そして、オールアットワンス評価を使用することで... Sql Serverで、中間変数/列なしでテーブルの列値を交換できます。

私の知る限り、ほとんどの RBDMS はこのように動作しますが、MySql は例外です。


編集:

効果は、割り当て間に参照がある場合にのみ表示されることに注意してください。

SELECTこれは、次のようなステートメントがある場合を意味すると理解しています。

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

次に、割り当てが実行される順序は関係ありません...何があっても同じ結果が得られます。しかし、次のようなものがある場合...

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

割り当て( ) の間に参照があり、とが割り当てられる@B = @A順序が重要になります。@A@B

于 2013-02-14T21:41:40.160 に答える