Еще один вопрос рефакторинга PL / SQL!
У меня есть несколько курсоров, которые имеют общую упрощенную форму:
cursor_1 is
with X as (select col1, col2 from TAB where col1 = '1'),
Y as (select col1, col2 from TAB where col2 = '3'),
/*main select*/
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'),
/*main select*/
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 ),
/*main select*/
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;
По сути, все эти курсоры (их более 3)те же сводные / отчетные запросы.Разница в факторизованных подзапросах.Всегда есть 2 факторизованных подзапроса, «X» и «Y», и они всегда выбирают одни и те же столбцы для подачи в основной отчетный запрос.
Проблема в том, что основной запрос отчетов ОЧЕНЬ большой, около 70линий.Само по себе это не так уж и плохо, но оно было скопировано для ВСЕХ запросов на отчеты (я думаю, их более десятка).
Поскольку единственное различие заключается в разложенных подзапросах (и все они возвращаютте же столбцы, на самом деле это просто разница в таблицах, из которых они выбирают, и в их условиях) Я надеялся найти способ реорганизовать все это так, чтобы был ОДИН запрос для гигантского отчета и меньший для различных факторизованных подзапросов, чтобы приВнесены изменения в способ составления отчета, мне нужно сделать это только в одном месте, а не в дюжине.Не говоря уже о гораздо более простом для навигации (и чтения) файле!
Я просто не знаю, как правильно выполнить рефакторинг чего-то подобного.Я думал, конвейерные функции?Я не уверен, что они подходят для этого, или, если есть более простой способ ...
С другой стороны, я также задаюсь вопросом, будет ли производительность значительно хуже, если разделить отчетный запрос.Производительность (скорость) является проблемой для этой системы.Я бы предпочел не вносить изменения для удобства разработчика, если он добавляет значительное время выполнения.
Полагаю, что мне в конечном итоге понравится то, что выглядит примерно так (я просто не уверен, каксделать это так, чтобы он действительно скомпилировался):
cursor main_report_cursor (in_X, in_Y) is
with X as (select * from in_X),
Y as (select * from in_Y)
/*main select*/
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;
...
(с использованием Oracle 10g)