Как я могу использовать пользовательскую функцию в операторе выбора в качестве курсора для достижения результатов? - PullRequest
1 голос
/ 07 февраля 2020

У меня ниже курсоров:

OPEN p_results FOR
      SELECT distinct S02.CONVERSATION_ID, S02.INTERNAL_USI, S02.PRN,  S02.CRN, 
             S01.EARLIEST_B_DATE "Bank Date", S01.EARLIEST_B_NARRATIVE||'DSEC' "BN", 
             abs(S01.TOTAL_B_AMOUNT - S02.TOTAL_C_AMOUNT) "GA", 
             decode(S01.EXTRA_FLAG_4,1,'OP',2,'UP') "Batch Status", 
             (case 
                when S01.latest_b_date > S02.latest_c_date then S01.latest_b_date 
                else S02.latest_c_date 
              end ) Effective_Date, S02.ICC_ID,  
             S02.MATCH_METHOD,
             S01.TOTAL_B_AMOUNT                     
      FROM TTPAY S01,   
           TTCONT S02    
      Where S01.EXTRA_FLAG_4 in (1,2) 
      and   S02.EXTRA_FLAG_4 in (1,2) 
      and   S01.Match_no = 0 
      and   S02.Match_no = 0 
      and S01.PRN = S02.PRN;

Для этого фрагмента кода я должен внести изменения, которые, если приведенная ниже дата вступления в силу является выходным или выпадает на выходные, то мне нужно добавить + 1 и в субботу +2, в противном случае я буду использовать результат, так как он возвращается в приведенном ниже коде в качестве даты_действия.

(case 
        when S01.latest_b_date > S02.latest_c_date then S01.latest_b_date 
        else S02.latest_c_date 
      end ) Effective_Date

У меня есть функция с именем WORKING_DAY, которая принимает одну дату в качестве параметра и возвращает логическое значение как TRUE или FALSE после проверки календаря праздников и выходных.

Как эффективно использовать эту функцию в приведенном выше фрагменте кода для получения требуемой даты?

Ответы [ 3 ]

0 голосов
/ 07 февраля 2020

Ваша функция в этом контексте практически бесполезна. Вы должны знать, является ли эффективная дата

  • субботой или
  • воскресеньем или
  • праздником или
  • ни один из этих

Поэтому, если он возвращает TRUE или FALSE, вы ничего не можете сделать с ним. Вам нужна новая функция, которая будет возвращать VARCHAR2, например, sun или sat или hol или null (представляющий рабочий день). Затем вы можете использовать его в запросе, который вы написали. Как? Простой способ - без использования касания кода, который у вас уже есть, - использовать его как встроенный вид:

   OPEN p_results FOR
      SELECT conversation_id,
             CASE                                                 --> this is where you decide
                WHEN working_day_vc (effective_date) = 'sat'      --> whether day is SAT/SUN/HOLIDAY
                THEN
                   effective_date + 2
                WHEN working_day_vc (effective_date) IN ('sun', 'hol')
                THEN
                   effective_date + 1
                ELSE
                   effective_date
             END
                effective_date
        FROM (
              -- this is your current query
              SELECT DISTINCT
                     S02.CONVERSATION_ID,
                     S02.INTERNAL_USI,
                     S02.PRN,
                     S02.CRN,
                     S01.EARLIEST_B_DATE "Bank Date",
                     S01.EARLIEST_B_NARRATIVE || 'DSEC' "BN",
                     ABS (S01.TOTAL_B_AMOUNT - S02.TOTAL_C_AMOUNT) "GA",
                     DECODE (S01.EXTRA_FLAG_4,  1, 'OP',  2, 'UP')
                        "Batch Status",
                     (CASE
                         WHEN S01.latest_b_date > S02.latest_c_date
                         THEN
                            S01.latest_b_date
                         ELSE
                            S02.latest_c_date
                      END)
                        Effective_Date,
                     S02.ICC_ID,
                     S02.MATCH_METHOD,
                     S01.TOTAL_B_AMOUNT
                FROM TTPAY S01, TTCONT S02
               WHERE     S01.EXTRA_FLAG_4 IN (1, 2)
                     AND S02.EXTRA_FLAG_4 IN (1, 2)
                     AND S01.Match_no = 0
                     AND S02.Match_no = 0
                     AND S01.PRN = S02.PRN);
0 голосов
/ 10 февраля 2020

Если это какой-то отчет и выполняется в sql. Например

with
  function wf_WORKING_DAY(p_Date date) return number is
  begin
    return case when WORKING_DAY(p_Date) then 1 else 0 end;
  end;
select wf_WORKING_DAY(date'2020-01-01')
  from dual
/
0 голосов
/ 07 февраля 2020

У меня есть функция с именем WORKING_DAY, которая принимает одну дату в качестве параметра и возвращает логическое значение как TRUE или FALSE после проверки календаря праздников и выходных.

Как использовать эта функция в приведенном выше фрагменте кода эффективно для получения требуемой даты?

Вы не можете использовать ее в выражении SQL, поскольку BOOLEAN является типом данных PL / SQL и не существует в SQL.

Если вы хотите вернуть истинное значение в SQL, верните литерал (т. е. 0 / 1 или 'Y' / 'N' et c.) И сравните, если нужно.

Таким образом, ваша функция должна быть изменена с возврата типа данных BOOLEAN (только PL / SQL) на:

CREATE FUNCTION is_working_day(
  dt IN DATE
) RETURN NUMBER
IS
  is_working_day BOOLEAN;
BEGIN
  -- do stuff.

  IF is_working_day THEN
    RETURN 1;
  ELSE
    RETURN 0;
  END IF;
END;
/

Обновление

после изменения функции, как я могу использовать эту функцию в этом фрагменте кода для получения требуемой даты вступления в силу?

Вы не можете использовать эту функцию, чтобы определить, сколько дней вам нужно добавить. Функция возвращает истинное значение, поэтому, если вы не собираетесь повторять каждый последующий день и проверять, является ли это рабочим днем ​​(что трудно сделать в SQL), то ваш текущий метод возврата истинного значения не будет работать.

Вместо этого переместите логи c в функцию, которая сообщает, сколько дней нужно добавить:

CREATE FUNCTION days_until_next_working_day(
  dt IN DATE
) RETURN INTEGER
IS
  current_day DATE := dt;
BEGIN
  WHILE NOT is_working_day( current_day ) LOOP
    current_day := current_day + INTERVAL '1' DAY;
  END LOOP;
  RETURN current_day - dt;
END;
/

(Вероятно, есть более эффективный способ написать это вычислять следующий рабочий день, а не повторять каждый последующий день, но мы не знаем, как вы определяете выходные, и т. д. c., поэтому мы не можем его оптимизировать.)

Тогда просто добавьте возвращаемое значение в ваш запрос SQL, чтобы пропустить это количество дней.

...