1

SQL Server Management Studioを使用すると、望ましくない結果が得られます(私にはバグのように見えます..?)

(other_tableのフィールドではなくFIELD)を使用する場合:

SELECT * FROM main_table WHERE field IN (SELECT FIELD FROM other_table)

main_tableからすべての結果を取得します。

正しいケースを使用する:

SELECT * FROM main_table WHERE field IN (SELECT field FROM other_table)

フィールドが他の場所に表示されると、期待どおりの結果が得られます。

サブクエリを独自に実行する:

SELECT FIELD FROM other_table

無効な列名エラーが発生します。

確かに私は最初のケースでこのエラーを取得する必要がありますか?

これは照合に関連していますか?DBはバイナリ照合です。ただし、サーバーでは大文字と小文字は区別されません。サーバーコンポーネントが「このコードはOKです」と言っており、フィールドが間違った名前であるとDBに言わせていないように思えます。

ソリューションの私のオプションは何ですか?

4

2 に答える 2

5

大文字と小文字の区別に依存しないものを使用して何が起こっているかを説明しましょう。

USE tempdb;
GO

CREATE TABLE dbo.main_table(column1 INT);

CREATE TABLE dbo.other_table(column2 INT);

INSERT dbo.main_table SELECT 1 UNION ALL SELECT 2;
INSERT dbo.other_table SELECT 1 UNION ALL SELECT 3;

SELECT column1 FROM dbo.main_table
WHERE column1 IN (SELECT column1 FROM dbo.other_table);

結果:

column1
-------
1
2

なぜそれはエラーを引き起こさないのですか?SQL Serverはクエリを調べて、内部のcolumn1がother_tableに存在しない可能性があることを確認しているため、外部参照テーブルに存在するcolumn1を推定して「使用」しています(テーブル参照のない外部テーブル)。このバリエーションについて考えてみてください。

SELECT [column1] FROM dbo.main_table
WHERE EXISTS (SELECT [column1] FROM dbo.other_table WHERE [column2] = [column1]);

結果:

column1
-------
1

ここでも、SQL Serverは、where句のcolumn1もローカルで参照されるテーブルに存在しないことを認識していますが、外部スコープでそれを見つけようとします。したがって、架空の世界では、クエリが実際に次のように言っていると考えるかもしれません。

SELECT m.[column1] FROM dbo.main_table AS m
WHERE EXISTS (SELECT m.[column1] FROM dbo.other_table AS o WHERE o.[column2] = m.[column1]);

(これは私が入力した方法ではありませんが、そのように入力した場合でも機能します。)

論理的に意味をなさない場合もありますが、これはクエリエンジンが行う方法であり、ルールを一貫して適用する必要があります。あなたの場合(しゃれは意図されていません)、さらに複雑な問題があります:大文字と小文字の区別。SQL ServerはFIELDサブクエリで見つかりませんでしたが、外部クエリでは見つかりました。だからいくつかのレッスン:

  1. 列参照の前には常にテーブル名またはエイリアスを付けてください(また、テーブル参照の前には常にスキーマを付けてください)。
  2. 常に大文字と小文字を区別して、テーブル、列、その他のエンティティを作成して参照してください。特に、バイナリまたは大文字と小文字を区別する照合を使用する場合。
于 2012-06-01T12:17:26.307 に答える
3

非常に興味深い発見。暗黙の義務は、常にサブクエリ内のテーブルにエイリアスを設定し、それらのエイリアスを使用して、列がどのテーブルからのものであるかを明示する必要があることです。サブクエリを使用すると、問題の原因である外部クエリのフィールドを参照できますが、シナリオでは、デフォルトが内部クエリのフィールドリストであるか、列のあいまいさのエラーが発生することに同意します。とにかく、以下のこの方法が常に推奨されます。

select * from main_table a where a.field in (select x.field from other_table x)

于 2012-06-01T11:54:20.480 に答える