创建两个表,其中一些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);
结果:
这是怎么回事? 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".
答案 0 :(得分:2)
这是正常的预期行为。与大多数编程语言一样,标识符在SQL中以这种方式解析。如果最内层范围中不存在标识符,则名称解析向外工作。如果最内层作用域中没有名为“id”的列,则在该作用域之外解析列名。这里,“id”被解析为o.id.你应该总是使用表前缀!
假设你写了
where exists (
select * from inner_table
where inner_table.inner_id = id
)
您肯定希望将标识符“id”解析为o.id,就像在您的示例中一样。如果在子查询中,您无法引用查询中其他表的列,那将是愚蠢的。
也就是说,如果某些SQL实现可以执行标记这样的查询的健全性检查也会很好,因为如果子查询中只有一个列带有FROM子句,那么它通常应该是表中的一列在子查询中。如果没有,它通常是一个错字(但仍然是合法的查询)。