Wydaje się być dobrym wariantem w przypadku, gdy istnieje indeks co najmniej effective_start_date
i effective_end_date
pola per_all_people_f
tabeli.
Idealnym wariantem dla tego zapytania jest
create index x_per_all_people_search on per_all_people_f(
effective_start_date,
effective_end_date,
person_id,
emp_flag
)
ale może być zbyt drogi w utrzymaniu (koszt dysku, szybkość wstawiania).
Ponadto kursor w treści pakietu musi zawierać podzapytanie i wyniki ponownego użycia funkcji:
cursor cur_var
is
select
EMP_2012,
EMP_2013,
(EMP_2013 - EMP_2012) Diff
from (
select
function_name('01-MAR-2012','31-MAY-2012') EMP_2012,
function_name('01-MAR-2013','31-MAY-2013') EMP_2013
from dual
);
Oczywiście najlepszym rozwiązaniem jest zminimalizowanie przełączania kontekstów i pobranie wszystkich wartości z pojedynczego zapytania SQL. Możesz także podać parametry bezpośrednio do kursora:
cursor cur_var(
start_1 date, end_1 date,
start_2 date, end_2 date
)
is
select
EMP_2012,
EMP_2013,
(EMP_2013 - EMP_2012) Diff
from (
select
(
select
count(distinct papf.person_id)
from
per_all_people_f papf
where
papf.emp_flag = 'Y'
and
effective_start_date >= trunc(start_1)
and
effective_end_date <= trunc(end_1)
) EMP_2012,
(
select
count(distinct papf.person_id)
from
per_all_people_f papf
where
papf.emp_flag = 'Y'
and
effective_start_date >= trunc(start_2)
and
effective_end_date <= trunc(end_2)
) EMP_2013
from dual
);
Z mojego punktu widzenia parametry funkcji/kursora są zbyt ogólne, może lepiej stworzyć wrapper, który jako parametry wejściowe przyjmuje numer kwartału i dwa lata do porównania.
I na koniec, jeśli wyniki planowane do użycia w PL/SQL (przypuszczam, że z powodu zwrócenia pojedynczego wiersza) w ogóle nie używają kursora, po prostu zwracają obliczone wartości poprzez parametry wyjściowe. Z innego punktu widzenia, jeśli chcesz uzyskać dane kwartalne za cały rok w jednym kursorze, bardziej wydajne może być zliczenie wszystkich kwartałów i porównanie ich w jednym zapytaniu.