sql – 具有外连接的查询在Oracle 12c中的行为不同

前端之家收集整理的这篇文章主要介绍了sql – 具有外连接的查询在Oracle 12c中的行为不同前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
关于Oracle 12c缺少的数据,我遇到了一个问题.

我看了一下代码,发现一个查询可以在mysql,mssql,oracle 11g上运行,但在oracle 12c中有不同的行为.

我已经推广了表格结构并进行了一些查询,并重现了这个问题.

create table thing (thing_id number,display_name varchar2(500));
create table thing_related (related_id number,thing_id number,thing_type varchar2(500));
create table type_a_status (related_id number,status varchar2(500));
create table type_b_status (related_id number,status varchar2(500));

insert into thing values (1,'first');
insert into thing values (2,'second');
insert into thing values (3,'third');
insert into thing values (4,'fourth');
insert into thing values (5,'fifth');
insert into thing_related values (101,1,'TypeA');
insert into thing_related values (102,2,'TypeB');
insert into thing_related values (103,3,'TypeB');
insert into thing_related (related_id,thing_id) values (104,4);

insert into type_a_status values (101,'OK');
insert into type_b_status values (102,'OK');
insert into type_b_status values (103,'NOT OK');

运行查询

SELECT t.thing_id AS id,t.display_name as name,tas.status as type_a_status,tbs.status as type_b_status
FROM thing t LEFT JOIN thing_related tr 
  ON t.thing_id = tr.thing_id
LEFT JOIN type_a_status tas 
  ON (tr.related_id IS NOT NULL 
      AND tr.thing_type = 'TypeA' 
      AND tr.related_id = tas.related_id)
LEFT JOIN type_b_status tbs 
  ON (tr.related_id IS NOT NULL 
      AND tr.thing_type = 'TypeB' 
      AND tr.related_id = tbs.related_id)

在Oracle 11g上(这里是SQL Fiddle):

ID | NAME   | TYPE_A_STATUS | TYPE_B_STATUS
 1 | first  |            OK | (null)
 2 | second |        (null) | OK
 3 | third  |        (null) | NOT OK
 4 | fourth |        (null) | (null)
 5 | fifth  |        (null) | (null)

但是,与Oracle 12c相同的架构,数据和查询

ID | NAME   | TYPE_A_STATUS | TYPE_B_STATUS
 1 | first  |            OK | (null)
 2 | second |        (null) | OK
 3 | third  |        (null) | NOT OK
 4 | fourth |        (null) | (null)

似乎第二个外部连接没有带回任何东西,因为在“thing_related”中没有行加入.但是我不明白为什么外连接在这种情况下不返回null,就像在Oracle 11g,MysqL等中一样.

我一直在研究和发现文档,Oracle 12c对外连接有一些增强功能,但没有突出显示会影响到这一点的更改.

有没有人知道为什么这只是为了Oracle 12c,而且我如何最好地重写这个工作在12c和维护与11g,MysqL等的兼容性?

编辑:附加计划

Oracle 11g:

Oracle 12c:

解决方法

更新:这是在12.1.0.2中修复.

这绝对看起来像12.1.0.1中的一个错误.我鼓励您通过Oracle支持创建一个服务请求.他们可能会找到一个修复或更好的工作.希望Oracle能够在以后的版本中为大家解决这个问题.通常情况下,与支持有关的最糟糕的部分是复制问题.但是由于您已经有非常好的测试用例,因此这个问题可能很容易解决.

可能有很多方法解决这个错误.但是很难判断哪种方法将始终起作用.您的查询重写可能现在可以工作,但是如果优化程序统计信息更改,则计划将在以后更改.

在12.1.0.1.0上适用于我的另一个选项是:

ALTER SESSION SET optimizer_features_enable='11.2.0.3';

但是,在运行查询之前,您需要记住始终更改此设置,然后将其更改回“12.1.0.1”.有一些方法可以在查询提示中嵌入,例如/ * OPT_PARAM(‘optimizer_features_enable”.11.0.3’)* /.但是由于某种原因在这里不起作用.或者也许您可以临时设置整个系统,并在修复或更好的解决之后更改它.

无论您使用哪种解决方案,请记住记录.如果查询看起来很奇怪,下一个开发人员可能会尝试“修复”它,并遇到同样的问题.

原文链接:https://www.f2er.com/mssql/82201.html

猜你在找的MsSQL相关文章