PostgreSQL Oracle 兼容性之 - PL/SQL pipelined
背景
在Oracle中可以使用pipelined来返回多条记录。
在PostgreSQL中对应的功能是setof 表示返回多条记录。
网上的一个例子:
Oracle supports pipelined functions.
e.g a split function which takes in a string (a,b,c) and returns a b and c on multiple rows.
Can you advise on how to migrate such a function into enterprisedb?
create or replace function split
(
p_list varchar2,
p_del varchar2 := ','
) return split_tbl pipelined
is
l_idx pls_integer;
l_list varchar2(32767) := p_list;
l_value varchar2(32767);
begin
loop
l_idx := instr(l_list,p_del);
if l_idx > 0 then
pipe row(trim(substr(l_list,1,l_idx-1)));
l_list := substr(l_list,l_idx+length(p_del));
else
pipe row(trim(l_list));
exit;
end if;
end loop;
return;
end split;
PostgreSQL:
对于以上例子的需求,可以使用现成的PostgreSQL函数来解决:
postgres=# select regexp_split_to_table('a-b-c-d','-');
regexp_split_to_table
-----------------------
a
b
c
d
(4 rows)
如果用户只是有返回多行的需求,则可以使用returns setof来解决。
例如:
postgres=# create or replace function split (text,text) returns setof text as $$
postgres$# select regexp_split_to_table($1,$2);
postgres$# $$ language sql strict;
CREATE FUNCTION
postgres=# select split('a-b-c-d','-');
split
-------
a
b
c
d
(4 rows)
postgres=# create or replace function rsf1(id int) returns setof int as $$
postgres$# declare
postgres$# begin
postgres$# for i in 0..abs(id) loop
postgres$# return next i;
postgres$# end loop;
postgres$# end;
postgres$# $$ language plpgsql strict;
CREATE FUNCTION
postgres=# select rsf1(10);
rsf1
------
0
1
2
3
4
5
6
7
8
9
10
(11 rows)