奇怪的DB2范围

时间:2012-04-03 20:08:58

标签: sql select scope db2

创建两个表,其中一些ID重叠。

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
  3. 的所有行中将overlap_in字段更新为1

    这是怎么回事? db2允许这个的任何解释?

    注意:DB2 Version:

    >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".
    

1 个答案:

答案 0 :(得分:2)

这是正常的预期行为。与大多数编程语言一样,标识符在SQL中以这种方式解析。如果最内层范围中不存在标识符,则名称解析向外工作。如果最内层作用域中没有名为“id”的列,则在该作用域之外解析列名。这里,“id”被解析为o.id.你应该总是使用表前缀!

假设你写了

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

您肯定希望将标识符“id”解析为o.id,就像在您的示例中一样。如果在子查询中,您无法引用查询中其他表的列,那将是愚蠢的。

也就是说,如果某些SQL实现可以执行标记这样的查询的健全性检查也会很好,因为如果子查询中只有一个列带有FROM子句,那么它通常应该是表中的一列在子查询中。如果没有,它通常是一个错字(但仍然是合法的查询)。

相关问题