5

毎日私は何か新しいことを学びます、それはそうです:)誰かが私に次のコードの振る舞いの背後にある理論的根拠を説明してもらえますか?

DECLARE @A INT

SET @A = 15
SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')

SELECT @A
-- Rsultset is NULL

SET @A = 15
SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'

SELECT @A
-- Resultset is 15

私が見たところ、結果セットがNULLの場合、SETは変数の値を変更しますが、SELECTは変更しません。これは通常のANSI動作ですか、それともT-SQL固有ですか?

もちろん、私がそうする場合SELECT @A = NULL、割り当ては正しく行われます。

4

4 に答える 4

4

最初のバージョンは、クエリの結果に A を設定します。

SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')

基本的selectにはスカラー コンテキストで、行が見つからない場合は と評価されnullます。

2 番目のバージョンは、結果セットの各行に A を設定します。

SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'

行がないため、A が割り当てられることはありません。もう一つの例:

declare @a int

select  @a = i
from    (
        select  1
        union all select 2
        union all select 3
        ) as SubQueryAlias(i)
order by
        i

select  @a

これにより、 に 3 つの値が割り当てられます@a。最後に割り当てられ3たのは であるため、クエリはそれを出力します。

于 2012-09-17T07:51:42.003 に答える
2

まあ、選択は行を返しません。したがって、実際には割り当てはありません。

その結果、セットには null が含まれます。

于 2012-09-17T07:51:47.637 に答える
2

句での変数の割り当ては、SELECTかなり予測不可能です。あなたが持っているとき:

SELECT @A = ...

結果セットに1 行だけ含まれている場合、値は適切に定義されています。複数の行が返される場合、値は任意の行に対して 1 回計算されるか、結果セット内の行数まで複数回計算される場合があります。

ただし、クエリがゼロ行を生成する場合、割り当ては実行されません。

于 2012-09-17T07:53:40.473 に答える
1
SET @A = (SELECT ValueThatDoesntExist 
                       FROM dbo.MyTable WHERE MyColumn = 'notfound')

ここでは、クエリの実行結果として NULL が返されます

しかし、あなたがするとき

SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'

クエリから何も返されません

于 2012-09-17T07:52:25.153 に答える