0

一部の ID が重複する 2 つのテーブルを作成します。

create table outer_table (
    id integer,
    overlap_in smallint default 0
);
create table inner_table (
    inner_id integer
);

次に、いくつかの一般的な ID を入力します。

insert into outer_table(id) values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;
insert into inner_table(inner_id) values 0, 1, 2;

次に、オーバーラップ インジケーターを更新します。しかし、誤って間違った列名を入力し、「inner_id」ではなく「id」とだけ書き、エイリアスを使用しないことにしました。

update outer_table o
set o.overlap_in = 1
where o.id in (select id from inner_table);

結果:

  1. SQL エラーなし
  2. outer_table のすべての行で、overlap_in フィールドを 1 に更新します。

これはどうして正常なのですか?db2がこれを許可する理由は何ですか?

注: DB2 バージョン:

>db2level
DB21085I  Instance "....." uses "64" bits and DB2 code release "SQL09075"
with level identifier "08060107".
Informational tokens are "DB2 v9.7.0.5", "...", "IP23285", and Fix Pack
"5".
4

1 に答える 1

2

これは正常な、予想される動作です。ほとんどすべてのプログラミング言語と同様に、識別子はSQLでこのように解決されます。識別子が最も内側のスコープに存在しない場合、名前解決は外側で機能します。最も内側のスコープに「id」という名前の列がない場合、列名はそのスコープの外で解決されます。ここで、「id」はo.idとして解決されます。常にテーブルプレフィックスを使用する必要があります!

あなたが書いたとしましょう

where exists (
  select * from inner_table
  where inner_table.inner_id = id
)

例のように、識別子「id」をo.idとして解決する必要があります。サブクエリ内で、クエリ内の他のテーブルの列を参照できない場合は、ばかげています。

とは言うものの、FROM句を含むサブクエリで言及されている列が1つしかない場合、通常はサブクエリのテーブルの列である必要があるため、一部のSQL実装がこのようなフラグ付きクエリの健全性チェックを実行できると便利です。 。そうでない場合、それは通常タイプミスです(ただし、それでも合法的なクエリです)。

于 2012-04-03T20:25:27.490 に答える