2012-04-03 40 views
0

創建兩個表格,其中某些ID重疊。奇怪的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; 

接下來,更新重疊指示符。但是,錯誤地,你輸入錯誤的列名稱,你只寫「id」而不是「inner_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". 

回答

2

這是正常的,預期的行爲。與大多數每種編程語言一樣,標識符在SQL中以這種方式解決。如果最內層範圍中不存在標識符,則名稱解析會向外運行。如果最內層範圍中沒有名爲「id」的列,那麼列名將在該範圍外解析。在這裏,「id」被解析爲o.id.你應該總是使用表前綴!

假設你寫了

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

你肯定會想要標識符「ID」,以解決爲o.id,就像它是在你的榜樣。如果在子查詢中,你將無法引用查詢中其他表的列。

也就是說,如果某些SQL實現可以執行標記爲這樣的標記查詢的完整性檢查也會很好,因爲如果子查詢中只有一列提及了FROM子句,則它通常應該是來自子查詢中的表。如果不是,通常是一個錯字(但仍然是一個合法的查詢)。