PLS-00653与管道化表函数的调用

Oracle 应用管道函数时出现PLS-00653:在 PL/SQL 定义域内不允许有聚集/表函数    

 

创建一个表类型的

create or replace type str_list as table of varchar(300) ;  

比如我们创建一个带pipelied 管道函数返回一张表或一个数据源数据的函数test5

create or replace function test5 return str_list pipelined  
is
begin   
pipe row('line1');
pipe row('line2');
pipe row('line3');
pipe row('line4');
return; --注意这边直接返回就可以了
end;  

和创建一个不带该管道函数同样也返回一张表的类型的函数test6

create or replace function test6
return str_list
is   
var_out str_list;
begin
var_out:=str_list();
var_out.extend(1);
var_out(1):='line1' ;
var_out.extend(1);
var_out(2):='line2' ;
var_out.extend(1);
var_out(3):='line3' ;
var_out.extend(1);
var_out(4):='line4' ;
return var_out;--这边必须有个输出参数作为返回值
end;

接下来我们创建一个存储过程去调用test5 和 test6   

create or replace procedure prc
is  
var_out str_list ;
begin  
--调用函数test5
--var_out:=test5();
--这边调用带pipelined的函数test5 直接报错PLS-00653: 在 PL/SQL 定义域内不允许有聚集/表函数   
--这是因为管道函数 需要用TABLE 操作符从 SQL 查询中调用它 所以这边不能直接赋值  
--这边要赋值可以这样修改
select test5() into var_out from dual;
for i in var_out.first()..var_out.last() loop
    dbms_output.put_line(var_out(i)) ;
end loop ; 
--调用函数test6
select test6() into var_out from dual;
for i in var_out.first()..var_out.last() loop
    dbms_output.put_line(var_out(i)) ;
end loop ;
var_out:=test6();
for i in var_out.first()..var_out.last() loop
    dbms_output.put_line(var_out(i)) ;
end loop ;
end;

可以在SQL语句中调用test5和test6:

HR@ prod> select * from table(test5());
 
COLUMN_VALUE
------------------------------------------------------------------------------------------------------------------------
line1
line2
line3
line4
 
HR@ prod> select * from table(test6());
 
COLUMN_VALUE
------------------------------------------------------------------------------------------------------------------------
line1
line2
line3
line4

由此可见非管道的表函数也可以table函数来转化为可以直接用在SQL语句中的表。

 

难道是在存储过程中调用pipelined 函数是不行的吗?  答案:是可以的。管道函数调用过程不能直接用":="进行赋值,我们可以采用上面使用赋值方式select test5() into var_out from dual; 

你可能感兴趣的:(plsql,oracle,PLS-00653,pipeline,表函数,数据库技术,SQL)