我正在尝试在包中返回一个表来创建一个函数。我希望在包中调用一次函数,但能够多次重复使用它的数据。虽然我知道我在Oracle中创建临时表,但我希望保持干燥。
到目前为止,这就是我所拥有的:
部首:
CREATE OR REPLACE PACKAGE TEST AS
TYPE MEASURE_RECORD IS RECORD (
L4_ID VARCHAR2(50),
L6_ID VARCHAR2(50),
L8_ID VARCHAR2(50),
YEAR NUMBER,
PERIOD NUMBER,
VALUE NUMBER
);
TYPE MEASURE_TABLE IS TABLE OF MEASURE_RECORD;
FUNCTION GET_UPS(
TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
STARTING_DATE_IN DATE,
ENDING_DATE_IN DATE
) RETURN MEASURE_TABLE;
END TEST;
体:
CREATE OR REPLACE PACKAGE BODY TEST AS
FUNCTION GET_UPS (
TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
STARTING_DATE_IN DATE,
ENDING_DATE_IN DATE
) RETURN MEASURE_TABLE IS
T MEASURE_TABLE;
BEGIN
SELECT ...
INTO T
FROM ...
;
RETURN T;
END GET_UPS;
END TEST;
标题编译,正文没有。一条错误信息是“没有足够的值”,这可能意味着我应该选择MEASURE_RECORD而不是MEASURE_TABLE。
我错过了什么?
答案 0 :(得分:32)
我想你想要pipelined table function。
这样的事情:
CREATE OR REPLACE PACKAGE test AS
TYPE measure_record IS RECORD(
l4_id VARCHAR2(50),
l6_id VARCHAR2(50),
l8_id VARCHAR2(50),
year NUMBER,
period NUMBER,
VALUE NUMBER);
TYPE measure_table IS TABLE OF measure_record;
FUNCTION get_ups(foo NUMBER)
RETURN measure_table
PIPELINED;
END;
CREATE OR REPLACE PACKAGE BODY test AS
FUNCTION get_ups(foo number)
RETURN measure_table
PIPELINED IS
rec measure_record;
BEGIN
SELECT 'foo', 'bar', 'baz', 2010, 5, 13
INTO rec
FROM DUAL;
-- you would usually have a cursor and a loop here
PIPE ROW (rec);
RETURN;
END get_ups;
END;
为简单起见,我删除了你的参数,并没有在函数中实现循环,但你可以看到原理。
用法:
SELECT *
FROM table(test.get_ups(0));
L4_ID L6_ID L8_ID YEAR PERIOD VALUE
----- ----- ----- ---------- ---------- ----------
foo bar baz 2010 5 13
1 row selected.
答案 1 :(得分:4)
要立即返回整个表格,您可以将SELECT更改为:
SELECT ...
BULK COLLECT INTO T
FROM ...
这仅适用于不太大的结果,因为它们都必须在返回之前在内存中累积;否则请考虑Charles建议的流水线功能,或者返回REF CURSOR。
答案 2 :(得分:0)
CREATE OR REPLACE PACKAGE BODY TEST AS
FUNCTION GET_UPS(
TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
STARTING_DATE_IN DATE,
ENDING_DATE_IN DATE
)RETURN MEASURE_TABLE IS
T MEASURE_TABLE;
BEGIN
**SELECT MEASURE_RECORD(L4_ID , L6_ID ,L8_ID ,YEAR ,
PERIOD,VALUE ) BULK COLLECT INTO T
FROM ...**
;
RETURN T;
END GET_UPS;
END TEST;