I am writing some PL/SQL and found myself falling into a repeptitive pattern:
cursor c_curs1 is
select a, b, c
from (...) big_subquery_1
where big_subquery_1.a_ind = 'Y'
cursor c_curs2 is
select a, b, c
from (...) big_subquery_2
where big_subquery_2.b_ind = 'R'
cursor c_curs3 is
select a, b, c
from (...) big_subquery_3
where big_subquery_3.c_ind = 'M'
...
type t_curs1_tab is table of c_curs1;
type t_curs2_tab is table of c_curs2;
type t_curs3_tab is table of c_curs3;
...
v_curs1_results t_curs1_tab := t_curs1_tab();
v_curs2_results t_curs2_tab := t_curs2_tab();
v_curs3_results t_curs3_tab := t_curs3_tab();
Then when processing the results, I have code like this:
open c_curs1;
fetch c_curs1 bulk collect into v_curs1_results;
close c_curs1;
if v_curs1_results.first is not null and v_curs1_results.last is not null then
for i in v_curs1_results.first .. v_curs1_results.last loop
/*Do something with field a in the results
Do something with field b in the results
Do something with field c in the results*/
....
end loop;
end if;
The code in the processing loop is the same for all cursors, as all 3 cursors return a,b,c – the only difference being which cursor is referenced. I wanted to refactor this into some sort of generic result-set processor, but I’m stuck here:
procedure sp_process_collection(in_collection t_curs1_tab) is ...
I can only call this with v_curs1_results, I can’t call it with v_curs2_results or I get a PLS-00306 wrong number of types or arguments... compiler error. Is there any way to do this generically so I only have to write one collection processing procedure? I have this pattern of cursor (returning the same three columns, always the same types) appears in several other parts of the same package, and the processing loop, while semantically the same is sometimes written with slightly different code. I’d very much like to centralize the processing in one procedure, I just can’d figure out how to do it in PL/SQL. I know PL/SQL doesn’t have generics (Which I think would have made a Java/C# solution fairly trivial), but I’m wondering if there’s another way to approach this problem that I just haven’t thought of.
(using Oracle 10g)
If the resulting columns are the same, there’s no reason to have three TYPE declarations. You just have one TYPE. Whether you need one or more variables of that TYPE depends on whether you need to hold the different data sets concurrently.