2016-11-21 5 views
0

今日、同僚がクエリを実行すると、なぜ、どのように失敗したのか説明できませんでした。 クエリは(抽象化)であった:無効な副選択を持つ照会が実行されるのはなぜですか?

UPDATE table1 
SET columnToUpdate = 1 
WHERE recordID IN (
SELECT recordID FROM table2 WHERE table2column IN (*list of values*)) 

問題は、彼がテーブルに両方のテーブルに存在し、表1のPKでPERSONID、のために、表1にのみ存在していると誤解レコードID、FKを持っていました2.

副選択が解決できないために照会が実行されなかったと思います(実際には、副選択だけを実行すると失敗します)。 代わりに上記のクエリを実行すると、以前はNULLと0の組み合わせであったtable1のすべてのレコードが更新されました。

これは簡単に修正できましたが、誰でもこの現象が発生する理由を説明できますか?

ありがとうございます!

+1

内部選択に失敗したことを意味するのはエラーですか? –

+2

これは、相関サブクエリが機能する方法です。確かに修正するのは簡単ですが、コーディングの習慣を変更して列の前にテーブルを指定すると、これらの種類のエラーを大幅に最小限に抑えることができます。 –

答えて

2

相関サブクエリと呼ばれます。それはあなたがrecordID列はあなただけでは、サブクエリを実行すると、それが失敗している理由であるtable2からないサブクエリでtable1から参照されるサブクエリ

の内側、外側のクエリの列を参照することができます。通常、Where節で参照されている外側のクエリの列が表示されますEXISTS/NOT EXISTSを使用した場合

+0

丁寧な答えですが、今はなぜそれが実行されているのか分かりますが、それでは、なぜそれがtable1のすべての値を更新したのですか?その選択で、本質的にtable1の全てのデカルト積を、table2の何ものに対してもチェックしていますか? (すなわち、すべてのテーブル1) – David

+1

これは、table2のいずれかの行が選択されている場合、それらの行の単一の値としてTable1.RecordIdを選択したため、すべてのレコードを更新しました。したがって、Table1.RecordId IN(Table1.RecordId)全く選択されていない – Cato

3

これらの理由から、常にテーブルのエイリアスとフィールド名にエイリアスを使用してください。そうしないと、単純に間違ってSQLを(正しく)フィールドをあなたが意図している以外のテーブルテーブル2にない場合は、テーブル1のクエリです。

UPDATE table1 t1 
SET t1.columnToUpdate = 1 
    WHERE t1.recordID IN (
    SELECT t2.recordID FROM table2 t2 WHERE t2.table2column IN (*list of values*)) 
関連する問題