将某些旧式连接转换为SQL-92样式时,a()意外地留在查询中.当我预期错误ORA-25156时,没有引发错误:旧样式外连接()不能与引发的ANSI连接一起使用.
我有以下表格:
create table inner_join (
id integer
, some_data varchar2(32)
);
insert into inner_join values (1, 'a');
insert into inner_join values (2, 'b');
create table outer_join (
id integer
, some_data varchar2(32)
);
insert into outer_join values(2, 'c');
insert into outer_join values(3, 'd');
正在转换如下(更复杂的)查询
select *
from outer_join oj
, inner_join ij
where ij.id = oj.id(+);
并且错误地将查询转换如下
select *
from outer_join oj
join inner_join ij
on ij.id = oj.id(+);
这会产生预期的结果,但是,它非常危险,因为:
>有人可以很容易地假设INNER JOIN而不是OUTER JOIN(猜测发生了什么……)从而在再次更改查询时导致意外错误
>展出的行为可能在将来发生变化,导致许多地方出现错误
>似乎是contradict the documentation
You cannot specify the (+) operator in a query block that also contains FROM clause join syntax.
>使用SQL-92标准的一个显着好处是,当代码中出现错误(即缺少连接条件)时,将出现错误
我总是希望ORA-25156应该被提升.
为了演示这个问题:如果我运行这些查询,我不会遇到错误
select *
from outer_join oj
join inner_join ij
on ij.id = oj.id(+);
ID SOME_DATA ID SOME_DATA
--- --------- --- ---------
2 c 2 b
1 a
select *
from inner_join ij
join outer_join oj
on ij.id = oj.id(+);
ID SOME_DATA ID SOME_DATA
--- --------- --- ---------
2 b 2 c
1 a
如果我添加第三个表
create table middle_join (
id integer
, some_data varchar2(32)
);
insert into middle_join values (1, 'e');
insert into middle_join values (2, 'f');
insert into middle_join values (3, 'g');
然后当旧式连接位于查询的“中间”时,没有错误
select *
from inner_join ij
join outer_join oj
on ij.id = oj.id(+)
join middle_join mj
on ij.id = mj.id;
ID SOME_DATA ID SOME_DATA ID SOME_DATA
--- --------- --- --------- --- ---------
1 a 1 e
2 b 2 c 2 f
如果连接位于查询的“结尾”,则会引发正确的错误(!).
select *
from inner_join ij
join middle_join mj
on ij.id = mj.id
join outer_join oj
on ij.id = oj.id(+);
on ij.id = oj.id(+)
*
ERROR at line 6:
ORA-25156: old style outer join (+) cannot be used with ANSI joins
为什么会这样?我如何确保在所有情况下都提出ORA-25156以避免容易出错和未来的问题?
我已经在12.1.0.1上对此进行了测试,但如果它特定于此版本,我会感到惊讶……