Sql 奇怪的DB2作用域

Sql 奇怪的DB2作用域,sql,select,scope,db2,Sql,Select,Scope,Db2,创建两个ID重叠的表 create table outer_table ( id integer, overlap_in smallint default 0 ); create table inner_table ( inner_id integer ); 接下来,用ID填充它们,一些常见的ID insert into outer_table(id) values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; insert into inner_tabl

创建两个ID重叠的表

create table outer_table (
    id integer,
    overlap_in smallint default 0
);
create table inner_table (
    inner_id integer
);
接下来,用ID填充它们,一些常见的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);
结果是:

  • 没有SQL错误
  • 它将字段中的重叠_更新为外部_表中所有行中的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".
    

    这是正常的、预期的行为。与大多数编程语言一样,标识符在SQL中也是这样解析的。如果最内部的作用域中不存在标识符,则名称解析将向外工作。如果最里面的作用域中没有名为“id”的列,则在该作用域之外解析列名。这里,“id”被解析为o.id。您应该始终使用表前缀

    假设你已经写信了

    where exists (
      select * from inner_table
      where inner_table.inner_id = id
    )
    
    您肯定希望标识符“id”被解析为o.id,就像您的示例中一样。如果在子查询中不能引用查询中其他表中的列,那将是愚蠢的

    这就是说,如果一些SQL实现可以进行健全性检查来标记这样的查询,那也很好,因为如果子查询中只有一列提到FROM子句,那么它通常应该是子查询中表中的一列。如果不是,那通常是一个打字错误(但仍然是一个法律问题)