| 含(+)操作符表达式 | 部分支持,有差异 | 对于使用OR操作符连接的外连接表达式,GaussDB仅支持OR操作符左右两侧均为同一单表的外连接表达式。 在(+)和OR操作符混用的场景下,GaussDB与Oracle的行为存在差异,以下是与Oracle 19c的对比说明: 公共语句 -- 执行以下建表语句并插入数据
CREATE TABLE a(id int, b int);
CREATE TABLE a2(id int, c int);
INSERT INTO a VALUES(1,1);
INSERT INTO a VALUES (null, 11);
INSERT INTO a VALUES (2, null);
INSERT INTO a VALUES (123,123);
INSERT INTO a VALUES (5, 500);
INSERT INTO a VALUES (null, 600);
INSERT INTO a2 VALUES(1,2);
INSERT INTO a2 VALUES (3,null);
INSERT INTO a2 VALUES (null, 22);
INSERT INTO a2 VALUES (234,234);
INSERT INTO a2 VALUES (5, 700);
INSERT INTO a2 VALUES (null, 800); - 示例一
SELECT * FROM a,a2 WHERE (a.id(+) = 1 AND a.id(+) <= 2) OR a2.id(+) = 1 ORDER BY 1,2,3,4; - GaussDB
gaussdb=# CREATE DATABASE gaussdb_o DBCOMPATIBILITY = 'ORA';
gaussdb=# \c gaussdb_o
-- 执行公共语句后再执行查询语句
gaussdb_o=# SELECT * FROM a,a2 WHERE (a.id(+) = 1 AND a.id(+) <= 2) OR a2.id(+) = 1 ORDER BY 1,2,3,4;
ERROR: Operator "(+)" is not allowed used with "OR" together
-- 切换至默认数据库,并删除gaussdb_o数据库(需按照实际情况修改数据库名)
gaussdb_o=# \c postgres
gaussdb=# DROP DATABASE gaussdb_o; - Oracle
-- 执行公共语句后再执行查询语句
SQL> SELECT * FROM a,a2 WHERE (a.id(+) = 1 AND a.id(+) <= 2) OR a2.id(+) = 1 ORDER BY 1,2,3,4;
ID| B| ID| C
----------|----------|----------|----------
1| 1| 1| 2
1| 1| 3|
1| 1| 5| 700
1| 1| 234| 234
1| 1| | 22
1| 1| | 800
2| | 1| 2
5| 500| 1| 2
123| 123| 1| 2
| 11| 1| 2
| 600| 1| 2
11 rows selected.
-- 清理本次示例新建的数据表(需按照实际情况修改表名)
SQL> DROP TABLE a;
SQL> DROP TABLE a2; GaussDB因不满足OR操作符左右两侧为同一单表的外连接表达式的限制,报错;Oracle不报错。 - 示例二
SELECT * FROM a,a2 WHERE a.id(+) = a2.id AND a.id(+) != 2 OR a.id(+) IS NULL AND a.id(+) = a2.id ORDER BY 1,2,3,4; - GaussDB
gaussdb=# CREATE DATABASE gaussdb_o DBCOMPATIBILITY = 'ORA';
gaussdb=# \c gaussdb_o
-- 执行公共语句后再执行查询语句
gaussdb_o=# SELECT * FROM a,a2 WHERE a.id(+) = a2.id OR a.id IS NULL AND a.id(+) = a2.id ORDER BY 1,2,3,4;
id | b | id | c
----+-----+-----+-----
1 | 1 | 1 | 2
5 | 500 | 5 | 700
| | 3 |
| | 234 | 234
| | | 22
| | | 800
(6 rows)
-- 提取公共表达式后,执行转化后的SQL语句
gaussdb_o=# SELECT * FROM a,a2 WHERE a.id(+) = a2.id AND (a.id(+) != 2 OR a.id(+) IS NULL) ORDER BY 1,2,3,4;
id | b | id | c
----+-----+-----+-----
1 | 1 | 1 | 2
5 | 500 | 5 | 700
| | 3 |
| | 234 | 234
| | | 22
| | | 800
(6 rows)
-- 切换至默认数据库,并删除gaussdb_o数据库(需按照实际情况修改数据库名)
gaussdb_o=# \c postgres
gaussdb=# DROP DATABASE gaussdb_o; - Oracle
-- 执行公共语句后再执行查询语句
SQL> SELECT * FROM a,a2 WHERE a.id(+) = a2.id OR a.id IS NULL AND a.id(+) = a2.id ORDER BY 1,2,3,4;
ERROR at line 1:
ORA-01719: outer join operator (+) not allowed in operand of OR or IN
-- 提取公共表达式后,执行转化后的SQL语句
SQL> SELECT * FROM a,a2 WHERE a.id(+) = a2.id AND (a.id(+) != 2 OR a.id(+) IS NULL) ORDER BY 1,2,3,4;
ID| B| ID| C
----------|----------|----------|----------
1| 1| 1| 2
5| 500| 5| 700
| | 3|
| | 234| 234
| | | 22
| | | 800
6 rows selected.
-- 清理本次示例新建的数据表(需按照实际情况修改表名)
SQL> DROP TABLE a;
SQL> DROP TABLE a2; GaussDB因满足OR操作符左右两侧均为同一单表的外连接表达式,因此不报错;Oracle则直接报错(ORA-01719)。 通过提取公共表达式a.id(+) = a2.id,转化后的SQL语句为 SELECT * FROM a,a2 WHERE a.id(+) = a2.id AND (a.id(+) != 2 OR a.id(+) IS NULL) ORDER BY 1,2,3,4; 在两种数据库中执行结果一致。 |