暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kingbase兼容Oracle语法--连接操作符(+)

金小仓 2021-12-07
914

1. 问题
Kingbase如何兼容Oracle加号(+)连接操作符?

2. 文档概述
本文主要是通过调研Oracle的加号(+)操作符的功能,然后分析如何基于Kingbase实现兼容Oracle加号(+)连接操作符。

3. Oracle加号(+)操作符功能调研
Oracle中的连接类型可以分为两类:

内连接(inner join);
外连接。而外连接又分为左外连接(left join)、右外连接(right join)和全外连接(full join)。
而左右外连接除了使用left join、right join语法,外连接还可以使用加号(+)连接操作符语法。但是如果使用加号(+)连接操作符语法时,需要有一些注意事项:

(+)操作符只能出现在where子句中,并且不能与outer join语法同时使用;
当使用(+)操作符执行外连接时,如果where子句中包含有多个条件,则必须在所有条件中都包含(+)操作符;
(+)操作符只适用于列,而不能用在表达式上;
(+)操作符不能与or和in操作符一起使用;
(+)操作符只能用于实现左右外连接,而不能用于实现完全外连接。
Oracle 12c(+)操作符实例分析:

1、创建数据源

create table t1 (i int, j int) ;
insert into t1 values ( 1,2);
insert into t1 values (2,2);
insert into ti values (3,1) ;
insert into t1 values (null, null);
create table t2 as select * from t1;
========与where条件混合使用==========
2、简单等值连接条件

SQL> select * from t1, t2 where t1.i = t2.i(+);

I J I J
--------- -------- ------- --------
1 2 1 2
2 2 2 2
3 1 3 1

已选择4行。
3、如果有单表条件但是没有join条件,则(+)被忽略

SQL> select * from t1, t2 where t2.i(+)= 2;

I J I J
---------- -------- ------- --------
1 2 2 2
2 2 2 2
3 1 2 2
2 2
已选择4行。
SQL>select * from t1, t2 where t2.i = 2;

I J I J
---------- -------- ------- --------
1 2 2 2
2 2 2 2
3 1 2 2
2 2
己选择4行。
4、增加left join的右表单表条件

SQL> select * from t1,t2 where t1.i = t2.i(+) and t2.j(+) = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2

3 1
已选择4行。
5、如果left join 的右表单表条件不带(+),则作为普通where条件

SQL> select * from t1,t2 where t1.i = t2.i(+) and t2.j = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
已选择2行。
6、如果增加left join的左表单表条件且带(+),没有意义,被忽略

SQL> select * from t1,t2 where t1.i = t2.i(+) and t1.j(+) = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
已选择2行。
SQL> select * from t1,t2 where t1.i = t2.i(+) and t1.j = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
已选择2行。
7、支持运算表达式

SQL> select * from t1, t2 where t1.i = t2.i(+) + 1;

I J I J
--------- -------- ------- --------
2 2 1 2
3 1 2 2
1 2

已选择4行。
8、支持like

SQL> select * from t1, t2 where t1.i like t2.j(+);

I J I J
---------- -------- ------- --------
1 2 3 1
2 2 1 2
2 2 2 2
3 1

己选择5行。
9、支持between and

SQL> select * from t1, t2 where t1.i between t2.i(+) and t2.j(+);

I J I J
---------- -------- ------- --------

3 1
2 2 2 2
2 2 1 2
1 2 1 2
已选择5行。
10、支持is

SQL> select * from t1, t2 where t1.i = t2.i(+) and t2.j(+) is not null;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
3 1 3 1

已选择4行。
11、不支持or

SQL> select * from t1, t2 where t1.i = t2.i(+) or t1.j = t2.j(+);
select * from t1, t2 where t1.i = t2.i(+) or t1.j = t2.j(+)

第1行出现错误:
ORA-01719: OR或IN操作数中不允许外部联接运算符(+)
12、 不支持not (A and B)

SQL> select * from t1,t2 where not (t1.i = t2.i(+) and t1.j = t2.j(+));
select * from t1,t2 where not (t1.i = t2.i(+) and t1.j = t2.j(+))

第1行出现错误:
ORA-01719: OR或IN操作数中不允许外部联接运算符(+)
13、 支持not A

SQL> select * from t1, t2 where not t1.i = t2.i(+);

I J I J
---------- -------- ------- --------
1 2 2 2
1 2 3 1
2 2 1 2
2 2 3 1
3 1 1 2
3 1 2 2

已选择7行。
14、 不支持IN多个值

SQL> select * from t1, t2 where t1.i in (t2.i(+), 3);
select * from t1, t2 where t1.i in (t2.i(+), 3)

第1行出现错误:
0RA-01719: OR或IN操作数中不允许外部联接运算符(+)
15、 支持IN一个值

SQL> select * from t1, t2 where t1.i in (t2.i(+));

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
3 1 3 1

已选择4行。
16、 不支持子查询

SQL> select * from t1,t2 where t2.i(+) = (select max(t1.i) from t1) ;
select * from t1, t2 where t2.i(+) = (select max(t1.i) from t1)

第1行出现错误:
0RA-01799:列不能外部联接到子查询

========与ON条件混合使用==========
17、 简单等值连接条件

SQL> select * from t1 left join t2 on t1.i = t2.i(+);

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2
3 1 3 1

已选择4行。
18、连接类型冲突报错

SQL> select * from t1 right join t2 on t1.i = t2.i(+);
select * from t1 right join t2 on t1.i = t2.i(+)

第1行出现错误:
ORA-01468: 一个谓词只能引用一个外部联接的表
19、 left join的右表单表条件加不加(+)都是on条件

SQL> select * from t1 left join t2 on t1.i = t2.i(+) and t2.j = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2

3 1
已选择4行。
SQL> select * from t1 left join t2 on t1.i = t2.i(+) and t2.j(+) = 2;

I J I J
---------- -------- ------- --------
1 2 1 2
2 2 2 2

3 1
已选择4行。
20、 left join的左表单表条件加(+)会冲突

SQL> select * from t1 left join t2 on t1.i = t2.i(+) and t1.j(+) = 2;
select * from t1 left join t2 on t1.i = t2.i(+) and t1.j(+) = 2

第1行出现错误:
ORA-01468: 一个谓词只能引用一个外部联接的表
21、 full join遇到连接操作符退化成1eft join的情况

SQL> select * from t1 full join t2 on t1.j = t2.i(+);

I J I J
---------- -------- ------- --------
3 1 1 2
1 2 2 2
2 2 2 2

已选择4行。
22、 full join退化成left join,增加右表单表条件

SQL> select * from t1 full join t2 on t1.j = t2.i(+) and t2.j(+) = 2;

I J I J
---------- -------- ------- --------
3 1 1 2
1 2 2 2
2 2 2 2

已选择4行。
23、 full join退化成left join, 不带(+)的右表单表条件转变为where条件

SQL> select * from t1 full join t2 on t1.j = t2.i(+) and t2.j = 2;

I J I J
---------- -------- ------- --------
3 1 1 2
1 2 2 2
2 2 2 2
己选择3行。
24、 full join退化成left join, 增加左表单表条件, (+)被忽略

SQL> select * from t1 fu1ll join t2 on t1.j = t2.i(+) and t1.j(+) = 2;

I J I J
---------- -------- ------- --------
1 2 2 2
2 2 2 2
3 1

已选择4行。
SQL> select * from t1 full join t2 on t1.j = t2.i(+) and t1.j = 2;

I J I J
---------- -------- ------- --------
1 2 2 2
2 2 2 2
3 1

已选择4行。
4.Kingbase与Oracle加号(+)特性对比
特性对比表




5. Parsetree的结构对比分析
5.1. 不带join on的

详见https://bbs.kingbase.com.cn/thread-14537-1-1.html?_dsign=30e0d4f9

5.2. 带join on的

详见https://bbs.kingbase.com.cn/thread-14537-1-1.html?_dsign=30e0d4f9

oraclev8eftparsetree

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论