2012-04-03 8 views
0

いくつかのIDが重複する2つのテーブルを作成します。奇妙なDB2スコープ

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); 

結果:それはouter_tableを先

内のすべての行にoverlap_inフィールドに1を更新

  • はどのようにこれはしても正常です

    1. ないSQLエラー?なぜ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". 
      
  • 答えて

    2

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

    あなたはあなたが確かに識別子「idは」それはあなたの例であると同じように、o.idとして解決されるようにしたいと思う

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

    を書いていたとします。サブクエリ内でクエリ内の他のテーブルの列を参照できない場合は、愚かなことになります。

    つまり、FROM句を持つサブクエリに列が1つしかない場合、通常はSQLの列である必要があるため、このようなクエリのフラグが立てられたサニティチェックを行うことができればいいでしょう。サブクエリのテーブルそうでない場合は、通常はタイプミスです(ただし、まだ法的クエリです)。