将一些旧式连接转换为 SQL-92 样式时 (+)
被意外留在查询中。当我预期错误 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(+);
这会产生预期的结果,但是,它非常危险,因为:
You cannot specify the (+) operator in a query block that also contains FROM clause join syntax.
我总是希望在应该提出 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 上测试过这个,但如果它特定于这个版本,我会感到惊讶......
最佳答案
我相信当您尝试在 ANSI 语法查询的 WHERE 子句中使用 (+) 时会引发错误。当您尝试在 ON 子句中执行此操作时没有错误,因为在 Oracle 旧的蹩脚语法中,ON 子句不存在。
我想您可以将 (+) 打包到 ON 中很麻烦,但错误是针对 WHERE 子句的。
关于sql - 我应该得到 ORA-25156 "old style outer join (+) cannot be used with ANSI join",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41979162/