考虑以下设置:
CREATE TYPE list_t AS VARRAY(10) OF NUMBER(10);
/
CREATE TABLE x (
id NUMBER(10),
list list_t
);
INSERT INTO x VALUES (0, list_t());
INSERT INTO x VALUES (1, list_t(1));
INSERT INTO x VALUES (2, list_t(1, 2));
我的直觉告诉我,以下查询应该产生相同的结果:
-- 1: Using 12c syntax with table constructor
SELECT x.id, x.list, y.column_value
FROM x
OUTER APPLY TABLE (x.list) y;
-- 2: Using 12c syntax with an explicit (+) operator
SELECT x.id, x.list, y.column_value
FROM x
OUTER APPLY TABLE (x.list)(+) y;
-- 3: Using 12c syntax with derived table
SELECT x.id, x.list, y.column_value
FROM x
OUTER APPLY (SELECT * FROM TABLE (x.list)) y;
-- 4: Using 11g syntax with old outer join (+)
SELECT x.id, x.list, y.column_value
FROM x, TABLE(x.list)(+) y;
-- 5: Using 12c standard syntax with LATERAL (works only on derived tables in this case)
SELECT x.id, x.list, y.column_value
FROM x
LEFT JOIN LATERAL (SELECT * FROM TABLE (x.list)) y ON 1 = 1;
但是,它们不会返回相同的结果。#1 的结果似乎是错误的:
结果 1
(表现得像CROSS APPLY
,似乎错了)
ID LIST COLUMN_VALUE
------------------------------------
1 TEST.LIST_T(1) 1
2 TEST.LIST_T(1, 2) 1
2 TEST.LIST_T(1, 2) 2
结果 2、3、4 和 5
ID LIST COLUMN_VALUE
------------------------------------
0 TEST.LIST_T()
1 TEST.LIST_T(1) 1
2 TEST.LIST_T(1, 2) 1
2 TEST.LIST_T(1, 2) 2
使用存储函数的替代方法
为了说明我的困惑,我可以添加一个只返回输入列表的存储函数:
CREATE OR REPLACE FUNCTION f (list list_t) RETURN list_t IS
BEGIN
RETURN list;
END f;
/
然后在原始查询中使用它:
-- 1: Using 12c syntax with table constructor
SELECT x.id, x.list, y.column_value
FROM x
OUTER APPLY TABLE (f (x.list)) y;
我现在得到了 4 行的预期结果:
ID LIST COLUMN_VALUE
------------------------------------
0 TEST.LIST_T()
1 TEST.LIST_T(1) 1
2 TEST.LIST_T(1, 2) 1
2 TEST.LIST_T(1, 2) 2
问题
这是 Oracle 12.2.0.1.0 中的错误,还是OUTER APPLY
构造TABLE
函数应该如何工作?