Lei*_*fel 5 oracle vendor-support windows oracle-11g-r2
我有一个与 Oracle 合作的案例,他们说他们无法重现这一点。在 11.2.0.1 或更低版本中运行以下命令会从这两个查询中生成两行,但在 11.2.0.2 中,除非删除 case 语句,否则第二个查询将返回三行。任何人都可以确认这种行为吗?
create table t1 as (select rownum+1 id1 from dual connect by rownum<=3);
create table t2 as (select rownum+1 id2 from dual connect by rownum<=2);
--Correct version that returns two rows.
SELECT t1.id1 id1, t2.id2 id2, t3.id3 id3
, DECODE(1,1,'a','b') "Case/Decode"
FROM t1
LEFT JOIN t2 ON t1.id1 = t2.id2
LEFT JOIN (SELECT 1 id3 FROM dual) t3 ON t3.id3 = t1.id1
WHERE (t2.id2 IS NOT NULL or t3.id3 IS NOT NULL);
--Incorrect version that returns three rows when it should return two.
SELECT t1.id1 id1, t2.id2 id2, t3.id3 id3
, case when 1=1 then 'a' else 'b' end "Case/Decode"
FROM t1
LEFT JOIN t2 ON t1.id1 = t2.id2
LEFT JOIN (SELECT 1 id3 FROM dual) t3 ON t3.id3 = t1.id1
WHERE (t2.id2 IS NOT NULL or t3.id3 IS NOT NULL);
Run Code Online (Sandbox Code Playgroud)
同样的问题似乎影响了以下内容,即使行数相同,它也会返回错误的数据。
create table t1 as (select rownum id1 from dual connect by rownum<=3);
--Correct version.
SELECT t1.id1, NVL(t2.id2,'NULL') id2, 'No' Case_Present, t2.Constant_Value
FROM t1
LEFT JOIN (select null id2, 'Should Be NULL' Constant_Value from dual) t2
ON t1.id1 = t2.id2;
--Incorrect version shows values for Constant_Value when it shouldn't.
SELECT t1.id1, NVL(t2.id2,'NULL') id2
, case
when 1=1 then ('Yes')
else ' '
end as Case_Present
, t2.Constant_Value
FROM t1
LEFT JOIN (select null id2, 'Should Be NULL' Constant_Value from dual) t2
ON t1.id1 = t2.id2;
Run Code Online (Sandbox Code Playgroud)
可以在托管 apex.oracle.com 的 11gR2 数据库上重现
以下查询结果为 3 行:
SELECT t1.*, t2.*, t3.dummy, case when 1=1 then 'a' else 'b' end "Case/Decode"
FROM t1
LEFT JOIN (select 1 dummy from dual) t3 ON t3.dummy = t1.id1
LEFT JOIN t2 ON t1.id1 = t2.id2
WHERE (t2.id2 IS NOT NULL or t3.dummy IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)
删除 CASE 选择会得到两行并将 t3.dummy 的值从“1”更改为空。
使用 EXPLAIN PLAN,可以看到添加 CASE 删除了 FILTER
"T2"."ID2" IS NOT NULL OR CASE WHEN ROWID IS NOT NULL THEN 1 ELSE NULL END IS NOT NULL"
Run Code Online (Sandbox Code Playgroud)
我怀疑优化器正在将链接重新调整为双。在内联视图中执行的到 Dual 的外部连接是非常奇怪的事情,所以我怀疑它不会影响很多人。