1

SQL Server 2008 R2、Windows 7 OS を使用しています。

サーバー内には、con1次の SQL ステートメントによって作成されたテーブルがあります。

CREATE TABLE [dbo].[con1](
    [digit_str] [nvarchar](50) NULL
) ON [PRIMARY]

表には、con1次の値があります。

 digit_str
----------------
    1
    1
    2
    3
    4
    5
    1.

データベースに対して次の SQL ステートメントを実行しました。

SELECT t1.digit FROM
(
select CAST(digit_str as int) as digit from con1 where RIGHT(digit_str,1) <> '.'
) as t1
where t1.digit <> 1

サーバーから次のエラーメッセージが表示されました。

nvarchar 値 '1' の変換中に変換に失敗しました。データ型 int に。

内部 SQL が最初に実行され、一時テーブルが作成されたと思ったt1ので1.、テーブルに含まれていないためt1、SQL パーサーはwhere t1.digit <> 1一時テーブルをフィルター処理するために使用しますt1

しかし、上記は正しくないように思われるので、上記のSQLの実行順序を説明できる人はいますか?

4

2 に答える 2

4

これは、SQL Server の既知の "機能" です。WHERE 句が SELECT 句の前に実行されると想定しないでください。

参照: SQL Server は非論理的なエラーを発生させてはならない

実際には、そうするのには十分な理由があります。A が B よりもはるかに小さい 2 つのテーブルを結合することを検討してください。

select CAST(A.col1 as int), A.col2, B.col3
from A join B ...
where ... isnumeric(A.col1) = 1

生成されたクエリ プランを検査すると、正しいか間違っているかに関係なく、SQL サーバーは A からのデータを B に対して結合する先頭の行としてストリーミングしcol2ます function on col1。後で関数を実行するためだけに持ち込むこともcol1、CAST のような些細なことのために、SQL Server はストリーミング プロセス中にデータを変換することもできます。

確かなことは、この戦略により、特定のクエリで SQL Server が少し速くなることです。しかし、純粋に論理的な観点から言えば、私はそれをバグと呼んでいます。

于 2012-10-03T00:47:35.670 に答える
0

動作を説明することはできませんが、次のようにすると、必要なものが得られます。

SELECT t1.digit FROM
(
select CAST(digit_str as int) as digit 
  from con1 
 where RIGHT(digit_str,1) <> '.' 
   AND digit_str <> '1'
) as t1

最後のwhere句がその変換を実行させている理由はわかりません.t1の結果セットからすでに除外されているはずです。

于 2012-10-03T00:40:56.550 に答える