| René Nyffenegger's collection of things on the web | |
|
René Nyffenegger on Oracle - Most wanted - Feedback
|
Using PIPELINED in PL/SQL | ||
|
Pipelined functions are useful if there is a need for a data source other than a table in a select statement.
First, some preparation:
set arraysize 1 alter session set nls_date_format='dd.mm.yyyy hh24:mi:ss';
The first step is to define the format of the rows that are going to be returned. In this case here, we're going to return a date followed by a varchar2(99).
create or replace type o_date_varchar2 as object ( d date, v varchar2(99) ) /
Also, a collection type for the type previously defined must be created:
create or replace type t_date_varchar2 as table of o_date_varchar2 /
Finally, the function. It is a pipelined function as indicated by the keyword pipelined.
create or replace function f_date_varchar2(j in integer) return t_date_varchar2
pipelined
as
a_date_varchar2 o_date_varchar2 := o_date_varchar2(null,null);
begin
for a in 1..j loop
select to_char(value), sysdate
into a_date_varchar2.v, a_date_varchar2.d
from sys.v_
where name ='bytes sent via SQL*Net to client';
pipe row (a_date_varchar2);
sys.dbms_lock.sleep(1);
end loop;
return;
end;
/
Here, we call f_date_varchar2, cast its return value as t_date_varchar2 (which is the return type of f_date_varchar2 and
put the entire expression into a table(...) thingie. This table thingie will the feel like a table although it isn't.
select * from table(cast(f_date_varchar2(20) as t_date_varchar2));
Cleaning up:
drop function f_date_varchar2; drop type t_date_varchar2; drop type o_date_varchar2; set arraysize 15 Pivot queries
Here's a table that assigns skills to users. A user can have 1 or more skills.
create table t_ ( usr Varchar2(10), skl Varchar2(10) );
The table is filled
insert into t_ values ('Jwa','skinning');
insert into t_ values ('Jwa','piercing');
insert into t_ values ('Jwa','tanning' );
insert into t_ values ('Jwa','writing');
insert into t_ values ('Jwa','reading');
insert into t_ values ('Rag','skinning');
insert into t_ values ('Rag','tanning' );
insert into t_ values ('Rag','molding');
insert into t_ values ('Qqq','swimming');
Now, we're interested in finding out which user has which skills. We desire to have on column per user. Following the steps outlined at the beginning of this
page, we create a pipelined function:
create or replace type t_vc as table of varchar2(4000);
/
create or replace function pivot return t_vc pipelined
as
v_last_usr t_.usr%type := null;
v_line varchar2(4000);
begin
for r in (select usr, skl from t_ order by usr) loop
if v_last_usr is null then
v_line:=rpad(r.usr,11) || ': ';
v_last_usr := r.usr;
end if;
if r.usr <> v_last_usr then
pipe row(v_line);
v_line:=rpad(r.usr,11) || ': ';
v_last_usr := r.usr;
end if;
v_line := v_line || rpad(r.skl,11);
end loop;
pipe row(v_line);
return;
end pivot;
/
And displaying the result:
select * from table(pivot);
And the result is:
Jwa : skinning piercing writing tanning reading Qqq : swimming Rag : skinning molding tanning
Cleaning up:
drop table t_; drop function pivot; drop type t_vc;
See also pivot queries with Oracle
and the pivot clause for alternative ways to achieve pivot results.
|