3

SQL サーバーがこのように動作するのはなぜですか。これをSQL 2005で実行しています。

IN 句は、サブクエリの列名を検証しませんが、外側のクエリのテーブル名に対して検証します。これは取得の例です

Create table #table1(col1 int, col2 char(10), col3 char(15));

Create table #table2(col10 int, col11 char(10), col2 char(15));


insert into #table1(col1, col2, col3)
select 1, 'one', 'three'

insert into #table1(col1, col2, col3)
select 2, 'two', 'three'

insert into #table1(col1, col2, col3)
select 3, 'three', 'four'


insert into #table2(col10, col11, col2)
select 1, 'one', 'three'

insert into #table2(col10, col11, col2)
select 2, 'two', 'three'

insert into #table2(col10, col11, col2)
select 3, 'three', 'four'


select * from #table1
where col1 IN
(select col1 from #table2)

「select col1 from #table2」を選択して実行すると、エラーが発生します

Msg 207, Level 16, State 1, Line 1
Invalid column name 'col1'.
4

2 に答える 2

13

なんで?サブクエリで外側のクエリから列を参照できると便利な場合が多いためです。この動作をオフにするために使用できる設定はありませんが、エイリアスを使用する習慣を身につけた場合は、エイリアスに関するほとんどの問題を回避する必要があります。

select * from #table1 t1
where t1.col1 IN
(select t2.col1 from #table2 t2)

エラーが発生します。

于 2012-09-07T13:39:13.343 に答える
6

問題なのはIN句ではありません。

これ:

SELECT * 
  FROM #table1
 WHERE col1 IN (SELECT col1 
                  FROM #table2)

...オプティマイザはcol1#table1からのものであると想定しているため、機能します。テーブルエイリアスを使用する場合、あいまいさはありません:

SELECT t1.* 
  FROM #table1 t1
 WHERE t1.col1 IN (SELECT t2.col1 
                     FROM #table2 t2)

... を取得しMsg 207: Invalid column errorます。

これは、DELETE および UPDATE ステートメントを使用する場合と同じ原則です。通常の構文では、削除または更新されるテーブルに別名を付けることができないためです。

于 2012-09-07T13:39:33.123 に答える