Я копался в этом большую часть дня, но до сих пор не смог найти правильный ответ.Я пытаюсь найти способ вернуть результаты запроса SQL в пользовательской функции.Все данные в нашей системе датируются как транзакциями, так и датами вступления в силу, и мы обычно должны сравнивать данные между двумя точками времени.Прямо сейчас я использую предложение WITH, чтобы получить два разных набора данных («До» и «После»).Проблема в том, что запросы, используемые для создания этих наборов данных, очень длинные, и каждый CTE - это одно и то же, только с разными датами вступления в силу.Я хотел бы найти способ создать функцию, в которую я могу передать даты вступления в силу / транзакции для сравнения, чтобы у меня не было такой избыточной логики в моем SQL.Вот подвох - у меня есть доступ только для чтения и я не могу создавать объекты в БД.Я читал, что могу обойтись оператором Declare, но пока не смог сделать это правильно.
Вот пример того, что у меня сейчас.Я значительно упростил запрос, так что это не полный беспорядок.
WITH effective_date AS (
SELECT to_date(:EFFDT) AS effdt,
to_date(:REPORT_DATE_BEFORE) AS report_dt_before,
to_date(:REPORT_DATE_AFTER) AS report_dt_after
FROM dual),
election_data_before AS (
SELECT *
FROM effective_date efd
CROSS JOIN elections e
WHERE efd.effdt >= e.start_dt
AND efd.effdt < e.until_dt
AND efd.report_dt_before >= e.tran_start_dt
AND efd.report_dt_before < e.tran_until_dt),
election_data_after AS (
SELECT *
FROM effective_date efd
CROSS JOIN elections e
WHERE efd.effdt >= e.start_dt
AND efd.effdt < e.until_dt
AND efd.report_dt_after >= e.tran_start_dt
AND efd.report_dt_after < e.tran_until_dt)
SELECT ...
FROM election_data_before edb
INNER JOIN election_data_after eda
ON edb.employee_id = eda.employee_id
AND edb.benefit_type = eda.benefit_type
WHERE ...
Это выглядит не так уж плохо, но, как я уже сказал, это чрезвычайно упрощено.Вот что я хотел бы сделать.Я знаю, что это мусорный код, просто пытаюсь проиллюстрировать то, что я рисую.
FUNCTION elections ( effdt date, report_dt date )
RETURN (
SELECT *
FROM elections e
WHERE effdt >= e.start_dt
AND effdt < e.until_dt
AND report_dt >= e.tran_start_dt
AND report_dt < e.tran_until_dt)
SELECT ...
FROM elections(:EFFDT, :REPORT_DT_BEFORE) edb
ON pp.employee_id = edb.employee_id
INNER JOIN elections(:EFFDT, :REPORT_DT_AFTER) eda
ON pp.employee_id = eda.employee_id
AND edb.benefit_type = eda.benefit_type
WHERE ...
Я читал о конвейерных функциях и анонимных блоках весь день, но не смог собрать их все вместе.Если кто-то может указать мне правильное направление или сообщить мне, если мне лучше, просто используя два разных CTE, я был бы признателен.Спасибо!