2012-04-03 78 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子句,则它通常应该是来自子查询中的表。如果不是,通常是一个错字(但仍然是一个合法的查询)。