管道函数返回表"不一致的数据类型:预期%s得到%s"

时间:2017-07-28 14:01:16

标签: oracle function pipeline

我试图创建一个管道函数来返回一个表,但我似乎无法正确获取语法。我已经关注了一些示例,并且数据类型不一致,我不明白为什么。我认为它在某种程度上会以与行定义不匹配的方式返回行。任何帮助将非常感激。在此先感谢。

DROP TYPE ODSMaxVRSN_TBL;
DROP TYPE ODSMaxVRSN_ROW;


CREATE OR REPLACE TYPE ODSMAXVRSN_ROW AS OBJECT
(
  audit_sls_trans_key     Number
,sls_tran_key                 NUMBER
,sls_4_part_key           varchar2(50),
sls_audit_rvsn_nbr      NUMBER,
sls_tran_key_unaud      NUMBER
)
/

CREATE OR REPLACE TYPE ODSMaxVRSN_TBL AS TABLE OF ODSMaxVRSN_ROW
/

create or replace FUNCTION GET_ODSMAXVRSN (in_dtFmt varchar2,in_start_date varchar2,in_end_date varchar2)
         RETURN ODSMAXVRSN_TBL PIPELINED IS 

l_row ODSMAXVRSN_ROW;
l_cursor  SYS_REFCURSOR; 
l_sql    VARCHAR2(2000);

begin

    l_sql := 'With 
sales as (
select s.SLS_TRANS_KEY,s.SLS_4_PART_KEY, nvl(s.SLS_AUDIT_RVSN_NBR,0) sLS_AUDIT_RVSN_NBR, 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
    , to_number(max(SLS_AUDIT_RVSN_NBR)) 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 
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
left outer join unaudited u on t.SLS_4_PART_KEY = u.SLS_4_PART_KEY';
SYS.DBMS_OUTPUT.PUT_LINE( l_sql);
    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;

select * from table(GET_ODSMAXVRSN('yyyy-mm-dd','2017-07-25','2017-07-31'))

1 个答案:

答案 0 :(得分:1)

也许试试这个:

pipe row ( ODSMAXVRSN_ROW(
   l_row.AUDIT_SLS_TRANS_KEY,
   l_row.SLS_TRANS_KEY,
   l_row.SLS_4_PART_KEY,
   l_row.SLS_AUDIT_RVSN_NBR,
   l_row.sls_trans_key)       
);

用于调试插入

SYS.DBMS_OUTPUT.PUT_LINE( 
   l_row.AUDIT_SLS_TRANS_KEY ||','||
   l_row.SLS_TRANS_KEY||','||
   l_row.SLS_4_PART_KEY||','||
   l_row.SLS_AUDIT_RVSN_NBR||','||
   l_row.sls_trans_key);

为了查看所有值是否都具有正确的数据类型。

最好将输入值设置为DATE数据类型,而不是VARCHAR2,即

create or replace FUNCTION GET_ODSMAXVRSN (
    in_start_date DATE,in_end_date DATE)
    RETURN ODSMAXVRSN_TBL PIPELINED IS 

...

    where s.REC_CRT_TS between :in_start_date and :in_end_date 

...

OPEN l_cursor FOR l_sql USING in_start_date, in_end_date;

如果你必须坚持使用VARCHAR2,你也可以尝试

create or replace FUNCTION GET_ODSMAXVRSN (
    in_dtFmt varchar2,in_start_date varchar2,in_end_date varchar2)
    RETURN ODSMAXVRSN_TBL PIPELINED IS 

...

    where s.REC_CRT_TS between :in_start_date and :in_end_date 

...

OPEN l_cursor FOR l_sql USING 
    TO_DATE(in_start_date, in_dtFmt), 
    TO_DATE(in_end_date, in_dtFmt);