SQL Objects and PLSQL
SQL Objects and PLSQL
SELECT column_value
from TABLE(
tab_varchar_4000( 'a','b','c')
);
FREE
There's a default collection type in
the database, granted to public
SYS.DBMS_DEBUG_VC2COLL
select * from
table(sys.dbms_debug_vc2coll
('a','b','c'))
Functions returning collections
CREATE FUNCTION gen_dates
(i_start in date, i_end in date)
RETURN tab_varchar_4000 IS
v_tab tab_varchar_4000 :=
tab_varchar_4000();
BEGIN
v_tab.extend(1 + i_end - i_start );
FOR i in 0..( i_end - i_start ) LOOP
v_tab(i+1) := i_start + i;
END LOOP;
RETURN v_tab;
END;
Pipelined functions
CREATE FUNCTION gen_dates
RETURN tab_varchar_4000 PIPELINED IS
CURSOR c_1 is
select sysdate dt from dual
connect by level < 100;
BEGIN
FOR i in c_1 LOOP
PIPE ROW (to_char(i.dt));
END LOOP;
RETURN;
END;
Wouldn't it be nice….
procedure p_test is
Begin
dbms_output.put_line('point 1');
. . .
dbms_output.put_line('point 2');
. . .
End;
Does not allow DML
Function p_test
return tab_varchar_4000 pipelined is
Begin
pipe row('point 1');
update….
pipe row('point 2');
End;
Must be at the top level
Procedure process_records is
procedure debug (p_text in varchar2)
is
begin
pipe row (p_text);
end;
Begin
. . .
End;
Warning – No Data Found
TABLE() functions
complete with a
NO_DATA_FOUND
It gets worse
Non-existent collection elements
also return a no_data_found
Pipelined Functions and
PL/SQL Collections
A PL/SQL collection type can also be used
in a pipelined function
select
mset('z','a','a','c','d','c')
multiset union distinct
mset()
from dual;
declare
x1 mset := mset('a','b');
x2 mset := mset('b','a');
begin
if x1 = x2 then
dbms_output.put_line('Match');
end if;
end;
Multiset operators in PL/SQL
declare
x1 mset := mset('a','b');
x2 mset := mset('b');
x3 mset;
begin
x3 := x1 multiset except x2;
dbms_output.put_line(x3.count
|| '.'||x3(1));
end;
Final Thought
For complex logic
SQL*Plus embedded
in shell scripts is
NOT
a good idea