Another PL / SQL refactoring issue!
I have several cursors that have a common simplified form:
cursor_1 is with X as (select col1, col2 from TAB where col1 = '1'), Y as (select col1, col2 from TAB where col2 = '3'), select count(X.col1), ... from X inner join Y on... group by rollup (X.col1, ... cursor_2 is with X as (select col1, col2 from TAB where col1 = '7' and col2 = '9' and col3 = 'TEST'), Y as (select col1, col2 from TAB where col3 = '6'), select count(X.col1), ... from X inner join Y on... group by rollup (X.col1, ... cursor_2 is with X as (select col1, col2 from TAB where col1 IS NULL ), Y as (select col1, col2 from TAB where col2 IS NOT NULL ), select count(X.col1), ... from X inner join Y on... group by rollup (X.col1, ... ... begin for r in cursor_1 loop print_report_results(r); end loop; for r in cursor_2 loop print_report_results(r); end loop; ... end;
In principle, all of these cursors (there are more than 3) are the same summaries / reports. The difference is in factorized subqueries. There are always two subqueries that are factorizable, βXβ and βYβ, and they always select the same columns to submit the main query to the report.
The problem is that the main reporting request is VERY large, about 70 lines. This in itself is not so bad, but it has been copied for ALL reporting requests (I think there are more than a dozen).
Since the only difference is the factorized subqueries (and they all return the same columns, this is really just the difference in the tables they select and their conditions). I was hoping to find a way to reorganize all this so that it is ONE query for a giant report and smaller for various factorized subqueries, therefore, when there are changes in how the report is made, I need to do this in only one place, not in a dozen. Not to mention a much easier (and readable) file to navigate!
I just donβt know how to properly reorganize something like this. I was thinking about pipelined functions? I'm not sure if they are suitable for this, or if there is an easier way ...
On the other hand, I also wonder if the performance will be significantly worse by splitting the reporting query. Performance (speed) is a problem for this system. I would prefer not to introduce changes for the convenience of developers if it adds significant runtime.
I assume that I end up like something that looks something like this (I'm just not sure how to do this so that it really compiles):
cursor main_report_cursor (in_X, in_Y) is with X as (select * from in_X), Y as (select * from in_Y) select count(X.col1), ... from X inner join Y on... group by rollup (X.col1, ... cursor x_1 is select col1, col2 from TAB where col1 = '1'; cursor y_1 is select col1, col2 from TAB where col2 = '3' ... begin for r in main_report_cursor(x_1,y_1) loop print_report_results(r); end loop; for r in main_report_cursor(x_2,y_2) loop print_report_results(r); end loop; ...
(using Oracle 10g)