包含使用 with 子句的 sql 的 oracle 管道函数
Posted
技术标签:
【中文标题】包含使用 with 子句的 sql 的 oracle 管道函数【英文标题】:oracle pipeline function containing sql using with clause 【发布时间】:2017-07-27 17:16:51 【问题描述】:我正在尝试创建一个函数,该函数返回一个对象,该对象可用作 select 语句中的表。根据对 oracle 文档的研究,我发现我需要一个 PIPELINED 函数。使用 sql 的管道函数的语法有问题。提前致谢!
DROP TYPE ODSMaxVRSN_ROW;
DROP TYPE ODSMaxVRSN_TBL;
CREATE OR REPLACE TYPE ODSMaxVRSN_ROW
AS OBJECT
(
sls_tran_key INT,
sls_tran_key_unaud int,
audit_sls_trans_key int,
sls_4_part_key varchar2(50),
sls_audit_rvsn_nbr VARCHAR2(25)
)
/
CREATE OR REPLACE TYPE ODSMaxVRSN_TBL AS TABLE OF ODSMaxVRSN_ROW
/
-- Declare the function
function GET_ODSMaxVRSN(in_dtFmt varchar2,
in_start_date varchar2,
in_end_date varchar2)
return ODSMaxVRSN_TBL pipelined is
rt ODSMaxVRSN_TBL;
l_sql VARCHAR2(2000);
l_cursor SYS_REFCURSOR;
begin
-- Your query to load the table type
l_sql := 'With sales as (
select s.SLS_TRANS_KEY,s.SLS_4_PART_KEY, nvl(s.SLS_AUDIT_RVSN_NBR,0), a.AUDIT_SLS_TRANS_KEY
from SLS_TRANS s
left outer join AUDIT_SLS_TRANS a
on s.SLS_4_PART_KEY = a.SLS_4_PART_KEY and a.SLS_AUDIT_RVSN_NBR = 1
where s.REC_CRT_TS between to_date(''' || in_start_date ||',''' || in_dtFmt || ') and to_date(''' || in_end_date ||',''' || in_dtFmt || ')''
and a.AUDIT_SLS_TRANS_KEY > 0
OR s.SLS_AUDIT_RVSN_NBR > 0
) , maxrvsn as (
Select trn.SLS_4_PART_KEY , max(n) SLS_AUDIT_RVSN_NBR
from sales trn
group by trn.sls_4_part_key
) , unaudited as (
select t.SLS_TRANS_KEY, t.SLS_4_PART_KEY, t.SLS_AUDIT_RVSN_NBR
from SLS_TRANS t
where t.SLS_AUDIT_RVSN_NBR is null
)
select t.AUDIT_SLS_TRANS_KEY, t.SLS_TRANS_KEY, t.SLS_4_PART_KEY, t.SLS_AUDIT_RVSN_NBR, u.sls_trans_key unaud_sls_trans_key
from sales t
inner join maxrvsn m on m.SLS_4_PART_KEY = t.SLS_4_PART_KEY and m.SLS_AUDIT_RVSN_NBR = t.SLS_AUDIT_RVSN_NBR
INNER join unaudited u on t.SLS_4_PART_KEY = u.SLS_4_PART_KEY';
OPEN l_cursor FOR l_sql;
FETCH l_cursor BULK COLLECT INTO rt;
CLOSE l_cursor;
-- Stuff the results into the pipeline..
if rt.count > 0 then
for i in rt.FIRST .. rt.LAST loop
pipe row (rt(i));
end loop;
end if;
-- Add more results as you please....
return;
end GET_ODSMaxVRSN;
/
【问题讨论】:
【参考方案1】:您可以尝试在循环中一次获取和管道一行,而不是执行BULK COLLECT
然后循环遍历表。例如,请参见此处:http://www.oracle-developer.net/display.php?id=429
function GET_ODSMaxVRSN(in_dtFmt varchar2,
in_start_date varchar2,
in_end_date varchar2)
return ODSMaxVRSN_TBL pipelined is
l_row ODSMaxVRSN_ROW;
l_sql VARCHAR2(2000);
l_cursor SYS_REFCURSOR;
begin
l_sql := '--your query--';
OPEN l_cursor FOR l_sql;
loop
fetch l_cursor into l_row;
exit when l_cursor%NOTFOUND;
pipe row (l_row);
end loop;
CLOSE l_cursor;
return;
end GET_ODSMaxVRSN;
/
【讨论】:
感谢您的建议。 当我尝试使用未定义的 l_sql 和 l_cursor 进行编译时,我仍然收到错误消息。还有什么需要补充的吗?以上是关于包含使用 with 子句的 sql 的 oracle 管道函数的主要内容,如果未能解决你的问题,请参考以下文章
在 Oracle 中使用 connect by 在 with 子句中访问子查询中的父别名