Oracle_应用管道函数时_pipelined

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

网友说:在实际的应用中,为了让PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成。REFCURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返回前,必须进行具体化。 9i 通过引入的管道化表函数纠正了后一种情况。表函数是返回整个行的集(通常作为一个集合)的函数,可以直接从SQL 语句中进行查询,就好像它是一个真正的数据库表一样。管道化表函数与之相似,但是它像在构建时一样返回数据,而不是一次全部返回。管道化表函数更加有效, 因为数据可以尽可能快地返回。

 自己总结:   管道化表函数 pipelined 必须返回一个集合。在函数中,PIPE ROW 语句被用来返回该集合的单个元素,该函数必须以一个空的RETURN 语句结束,以表明它已经完成。一旦我们创建了上述函数,我们就可以使用TABLE 操作符从 SQL 查询中调用它。

也就是实际操作当中我们需要是一个数据源 而不仅是一张表 所以用到管道化表函数,而且用这个函数在返回大数据时候传输的速度比较快


下面是有关 pipelined在生活中的 用遇到的一些问题:

1.创建一个表类型的B

 create or replace type T as tableof varchar(300)

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

create or replace function A(paras varchar2)

return T pipelined

is

begin

 ....

return;--注意这边直接返回就可以了

end A;

 

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

create or replace function B(paras varchar2)

return T

is

var_out T;

begin

 ....

return var_out;--这边必须有个输出参数作为返回值

end B;

 

3.接下来我们创建一个存储过程C 去调用A 和 B

create or replace procedure C(paras varchar2)

is

var_out T;

begin

 --  方法(1)

 T:=A('parasValues');--这边调用带pipelined  函数的函数A ---直接报错  PLS-00653: 在 PL/SQL 定义域内不允许有聚集/表函数

这是因为管道函数需要用TABLE 操作符从 SQL 查询中调用它 所以这边不能直接赋值

这边要赋值可以这样修改

select A('parasValues') into T from dual; 就可以

-- 方法 (2)

 T:=B('parasValues');--这边调用函数B

....

end C;

难道是在存储过程中调用pipelined 函数是不行的吗?

答案:是可以的。管道函数调用过程不能直接用":="进行赋值

我们可以采用上面使用赋值方式selectA('parasValues') into T from dual;

下面是提供一个完整管道函数拆分字符串  代码我已经测试过没问题 。pl/sql执行就OK

--创建类型

createorreplacetype type_split astableofvarchar2(50);

--创建管道函数

createorreplacefunction split

(

   p_list varchar2,

   p_sep varchar2 := ','

return type_split pipelined  --管道函数关键字

 is

   l_idx  pls_integer;

   v_list  varchar2(50) := p_list;

begin

   loop

      l_idx :=instr(v_list,p_sep);

      if l_idx > 0then

          piperow(substr(v_list,1,l_idx-1));

          v_list :=substr(v_list,l_idx+length(p_sep));

      else

          piperow(v_list);

          exit;

      endif;

   endloop;

   return;

end split;

 

--测试改管道函数是否正确

selectcolumn_valuefromtable(split('Hello,Cnblogs!',','));

--在存储过程调用运用该管道函数

createorreplaceprocedure prc(para outvarchar2) is

    var_out varchar2(200);

    var_split type_split;

  begin

  --调用方式一输出拆分的字符串

   for p in (selectcolumn_valuefromtable(split('Hello,Cnblogs!',',')))

  loop

  var_out:=var_out||p.column_value;

  endloop;

  --调用方式二输出拆分的字符串

  select split('Hello,Cnblogs!',',') into var_split from dual;

  for i invar_split.first()..var_split.last()

  loop

    var_out:=var_out||var_split(i);

     dbms_output.put_line(var_split(i));

  endloop;

  para:=var_out;

  end prc;

---以上是生活中遇到一些问题 写下来 希望对大家有用 如果不明白的问题可以留言或者加我QQ873557694

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值