我习惯了SQL Server,所以Oracle对我来说是新的。我需要在Oracle中执行一个表值函数,我从不同的站点拼凑了以下代码。我需要传入一个参数。前两个create语句似乎运行良好,没有错误。但是,Create函数会出现以下错误:
PLS-00306:调用“TBL_CREATININES”时参数的数量或类型错误
下面是完整的代码:
CREATE OR REPLACE TYPE tbl_lab_row AS OBJECT (
EVENT_END_DT_TM DATE,
RESULT_VAL VARCHAR2(255 CHAR),
RESULT_UNITS_CD NUMBER,
EVENT_CD NUMBER
);
CREATE OR REPLACE TYPE tbl_creatinines AS TABLE OF tbl_lab_row;
CREATE OR REPLACE FUNCTION tvf_creatinine_for_enc(p_enc_id NUMBER)
RETURN tbl_creatinines PIPELINED
IS
BEGIN
FOR r IN (SELECT EVENT_END_DT_TM, RESULT_VAL, RESULT_UNITS_CD, EVENT_CD
FROM SCHEMA.TABLE
WHERE ENCNTR_ID = p_enc_id AND EVENT_CD IN(...listed codes here removed for brevity
))
LOOP
PIPE ROW (tbl_creatinines(r.EVENT_END_DT_TM, r.RESULT_VAL, r.RESULT_UNITS_CD, r.EVENT_CD));
END LOOP;
RETURN;
END;
任何帮助都非常感谢。
2条答案
按热度按时间ru9i0ody1#
管道表函数需要管道 singular 对象类型,然后将自动转换为 nested 表类型。我修改了下面的函数以使其正确工作,尽管我使用了
DUAL
和硬编码值以避免创建表。但并非所有表函数都是流水线的。构建一个只返回嵌套变量的函数通常更容易,也可能更快。这种方法的缺点是,一个大的嵌套表变量可能会消耗大量内存。不要使用这种方法返回大量数据。
2jcobegt2#
如果你需要将参数“推送”到SQL代码深处,而通过
where
条件推送的一般 predicate 没有访问权限(类似于参数化视图),你可以使用SQL宏(自19.7起可用)作为管道函数的替代方案。好处是SQL宏返回与其他SQL代码合并的SQL代码,并且您不需要创建新类型。缺点是你不能在内部执行逐行处理(只要它返回一部分SQL代码),但其中一些可以使用可用的SQL结构来执行,如递归CTE,内联函数声明(
with function <funcname> ...
),match_recognize
,model
,横向连接等。fiddle