5

私は(あなたが思うだろうが)コンパイルしないが、代わりにターゲットテーブルからすべての行を削除するSQLの一部を持っています。

この設定を検討してください。

create table TableA (ColumnA varchar(200));
create table TableB (ColumnB varchar(200));

insert TableA values ('A'),('B'),('C');
insert TableB values ('A');

次に、次のSQL:

--Returns all rows from TableA
select * from TableA;

--Does not error (ColumnA does not exist on TableB)
delete TableA where ColumnA in (select ColumnA from TableB)

--No Rows are returned
select * from TableA;

上記のdeleteステートメントにより、に存在しないTableAエラーではなく、すべての行がから削除されます。ColumnATableB

これを実証するSQLフィドルがここにあります:http ://www.sqlfiddle.com/#!3/9d883/6

ColumnAfromTableAがピックアップされているようですが、 「範囲外」であると予想されていました。

どうしてこれなの?

4

2 に答える 2

4

内部クエリのColumnAと外部クエリの相関関係により、これは期待どおりに機能します。

この一般的に使用される相関クエリパターンは有効です

DELETE TableA WHERE NOT EXISTS (select * from TableB where TableB.ID=TableA.ID)

TableBに依存レコードがないTableAエントリを削除します。

これは、相関クエリでTableA列を参照できることを示しています。クエリで

delete TableA where ColumnA in (select ColumnA from TableB)

内部クエリは生成しています

  • TableBのレコードごとに1行
  • 各行に1つの列があり、その値は外部クエリのColumnAです。

したがって、DELETEは通過します

于 2012-10-11T17:36:26.877 に答える
3

混乱は理解できますが、正常に動作しています。ColumnAはまだ「範囲内」です。実際、必要に応じてサブクエリに参加することもできます。角かっこは範囲を制限するものではありませんが、読みやすさの観点から、それが生み出す混乱を見ることができます。

これは、列名の前に常にテーブル名(またはエイリアス)を付けることをお勧めするもう1つの例です。

于 2012-10-11T17:39:29.427 に答える