如何解决Oracle - 分组集和流水线表函数预期 NUMBER 得到 ROW
我正在使用 GROUPING SETS
处理带有汇总逻辑的报告,但出现此错误:
SELECT c1,c2,c3,SUM(c4) AS MySum
FROM TABLE(get_data()) src
GROUP BY GROUPING SETS ((c1,c3),(c1,c2),c1,());
-------------------------
ORA-00932: inconsistent datatypes: expected NUMBER got XXX.MYROW
00932. 00000 - "inconsistent datatypes: expected %s got %s"
当我只分别包含 c1
或 c2
时它工作正常:
GROUP BY GROUPING SETS ((c1,());
GROUP BY GROUPING SETS ((c1,());
SELECT c1,SUM(c4) AS MySum
FROM t1 src
GROUP BY GROUPING SETS ((c1,());
我错过了什么?我觉得这很简单。这是我的设置的简化示例:
-- Base table
CREATE TABLE t1 (c1 VARCHAR(10),c2 VARCHAR(10),c3 VARCHAR(10),c4 INTEGER);
-- Row type
CREATE TYPE myrow AS OBJECT (c1 VARCHAR(10),c4 INTEGER);
-- Table type
CREATE OR REPLACE TYPE mytable AS TABLE OF myrow;
-- Get data function
CREATE OR REPLACE FUNCTION get_mydata
RETURN mytable PIPELINED AS
BEGIN
FOR v_rec IN (
SELECT c1,c4
FROM t1
) LOOP
PIPE ROW (myrow(v_Rec.c1,v_Rec.c2,v_Rec.c3,v_Rec.c4));
END LOOP;
RETURN;
END;
数据库版本 - 12.1.0
ORA-22905: cannot access rows from a non-nested table item 22905.
00000 - "cannot access rows from a non-nested table item"
*Cause: attempt to access rows of an item whose type is not kNown
at parse time or that is not of a nested table type
*Action: use CAST to cast the item to a nested table type
解决方法
我不知道为什么它不起作用,但是 - 看看这个解决方法是否有帮助(使用 CTE 和 materialize
提示):
SQL> with test as
2 (select /*+ materialize */
3 c1,c2,c3,c4
4 from table(get_mydata()) src
5 )
6 select c1,sum(c4) as mysum
7 from test
8 group by grouping sets ((c1,c3),(c1,c2),c1,());
C1 C2 C3 MYSUM
---------- ---------- ---------- ----------
1 2 3 4
1 4
2 4
4
1 2 4
SQL>
,
您可以通过使用非流水线函数和 BULK COLLECT
来解决该错误:
CREATE OR REPLACE FUNCTION get_mydata2
RETURN mytable AS
v_data mytable;
BEGIN
SELECT myrow(c1,c4)
BULK COLLECT
INTO v_data
FROM t1;
RETURN v_data;
END;
/
我能够在版本 19c 中重现您的错误,因此您似乎发现了一个相对较大的 Oracle 错误。根据我的经验,流水线函数通常比常规函数更容易出错,并且往往会被过度使用。流水线函数可以更快地返回数据,但由于您的查询正在聚合所有行,因此无论如何您都不会看到性能提升。
非流水线函数方法的主要问题是您的会话将需要足够的内存来一次性存储 BULK COLLECT
的所有结果。如果您必须处理数百万个宽行,这可能不可行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。