Автоматическое определение даты за предыдущие месяцы в PLSQL

#database #oracle #plsql #rdbms

Вопрос:

Здравствуйте, у меня есть процедура и вопросы по этому поводу. Эта процедура используется для извлечения данных с последующей вставкой их в одну таблицу. Когда я тестирую свой код, я должен ввести некоторые параметры для выполнения процедуры.

 `--this is how I execute the procedure
begin
    GPU_DATA_EXTRACTOR(to_date('31/08/2021','DD/MM/YYYY'));
end;`
 

Но я хочу сделать так, чтобы, когда параметр billdate равен НУЛЮ, процедура автоматически выполнялась в последний день предыдущего месяца в качестве параметра. Как я могу внести это изменение? Я открыт для любых советов по обновлению, спасибо вам отныне.
Обновил приведенный ниже сценарий.

         create or replace procedure GPU_DATA_EXTRACTOR_TEST(pid_billdate DATE DEFAULT LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE), -1))) is
c_limit   CONSTANT PLS_INTEGER DEFAULT 10000;

CURSOR c1 IS
SELECT DISTINCT intl_prod_id
      FROM apld_bill_rt abr,
           acct_bill ab
      WHERE abr.CHRG_TP = 'INSTALLMENT'
          AND abr.TAX_CATG_ID = 'NOTAX'
          AND abr.acct_bill_id = ab.acct_bill_id
          AND ab.bill_date = pid_billdate;

TYPE prod_ids_t IS TABLE OF apld_bill_rt.intl_prod_id%TYPE INDEX BY PLS_INTEGER;
l_prod_ids   prod_ids_t;
begin

   execute immediate 'truncate table GPU_INV_TEST';

  OPEN c1;

  LOOP
     FETCH c1 BULK COLLECT INTO l_prod_ids LIMIT c_limit;
     
     EXIT WHEN l_prod_ids.COUNT = 0;

    FORALL indx IN 1 .. l_prod_ids.COUNT
    
      INSERT INTO GPU_INV_TEST
         SELECT AB.ACCT_BILL_ID,
                AB.BILL_NO,
                AB.INV_ID,
                AB.BILL_DATE,
                ba2.bill_acct_id,
                ba1.bill_acct_id parent_bill_acct_id,
                AB.DUE_DATE,
                PG.CMPG_ID,
                ABR.NET_AMT,
                AB.DUE_AMT,
                P.PROD_NUM,
                pds.DST_ID,
                ABR.DESCR,
                p.intl_prod_id
           FROM apld_bill_rt abr,
                acct_bill ab,
                prod p,
                FCBSADM.PROD_DST pds,
                bill_acct_prod bap,
                bill_acct ba1,
                bill_acct ba2,
                prod_cmpg pg
          WHERE ab.intl_bill_acct_id = ba1.intl_bill_acct_id
                AND AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID
                AND ba1.intl_bill_acct_id = ba2.parent_bill_acct_id
                AND ba2.intl_bill_acct_id = bap.intl_bill_acct_id
                AND bap.intl_prod_id = abr.intl_prod_id
                AND ABR.CHRG_TP = 'INSTALLMENT'
                AND bap.intl_prod_id = pds.intl_prod_id
                AND bap.intl_prod_id = p.intl_prod_id
                AND p.intl_prod_id = pg.intl_prod_id( )
                AND ABR.intl_prod_id = l_prod_ids(indx)
UNION
    SELECT AB.ACCT_BILL_ID,
                AB.BILL_NO,
                AB.INV_ID,
                AB.BILL_DATE,
                ba1.bill_acct_id,
                ba1.bill_acct_id parent_bill_acct_id,
                AB.DUE_DATE,
                PG.CMPG_ID,
                ABR.NET_AMT,
                AB.DUE_AMT,
                P.PROD_NUM,
                pds.DST_ID,
                ABR.DESCR,
                p.intl_prod_id
           FROM apld_bill_rt abr,
                acct_bill ab,
                prod p,
                FCBSADM.PROD_DST pds,
                bill_acct_prod bap,
                bill_acct ba1,
                prod_cmpg pg
          WHERE ab.intl_bill_acct_id = ba1.intl_bill_acct_id
                AND AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID
                --AND ba1.intl_bill_acct_id = ba2.parent_bill_acct_id
                AND ba1.intl_bill_acct_id = bap.intl_bill_acct_id
                AND bap.intl_prod_id = abr.intl_prod_id
                AND ABR.CHRG_TP = 'INSTALLMENT'
                AND bap.intl_prod_id = pds.intl_prod_id
                AND bap.intl_prod_id = p.intl_prod_id
                AND p.intl_prod_id = pg.intl_prod_id( )
                AND ABR.intl_prod_id = l_prod_ids(indx);

      
    COMMIT;  
    
    END LOOP;
   CLOSE c1;
end;
 

Комментарии:

1. @Gar что вы думаете по этому поводу?

Ответ №1:

Вы можете добавить значение по умолчанию для своих параметров. Возьмем в качестве примера следующую функцию:

 CREATE OR REPLACE FUNCTION sf_showDefault
(
  p_in DATE DEFAULT LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE), -1))
)
RETURN DATE
IS
BEGIN
  RETURN p_in;
END sf_showDefau<
/
 

Когда параметры не вводятся, он усекается SYSDATE и вычитает один месяц, а затем, если находит последний день этого месяца. Все, что делает функция, — это возвращает эти данные (или те, которые вы передаете…если вам так хочется).

Вот файл базы данных, показывающий влияние DEFAULT параметров (ССЫЛКА)

Комментарии:

1. Здравствуйте, спасибо за ваш ответ. Как вы думаете, в какую строку мне следует добавить эту функцию внутри процедуры? Мой второй вопрос: что будет с выполнением сценариев, если это сработает? (Я предполагаю, что начать GPU_DATA_EXTRACTOR; конец; Но не уверен

2. @burakzbc Функция-это всего лишь пример. Если вы хотите использовать его в своей процедуре, просто скопируйте DEFAULT LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE), -1)) и поставьте его после слова DATE в определении параметра.

3. Здравствуйте, определение успешно скомпилировано, но у меня есть только записи о дате 31/8/2021 в среде разработчика. Поэтому, когда я выполняю процедуру тестирования без параметра, она работает, но ничего не вставляет в таблицу. как вы думаете, какая должна быть причина? Это из-за того, что у меня запись только в августе или что-то еще? Я проверил с «-2». Он тоже не вставляется

4. Моя первая строка такова, кстати// создайте или замените процедуру GPU_DATA_EXTRACTOR_TEST(pid_billdate ДАТА ПО УМОЛЧАНИЮ ПОСЛЕДНИЙ ДЕНЬ(ADD_MONTHS(TRUNC(SYSDATE), -1)))

5. Поскольку мы сейчас находимся в октябре, я бы ожидал, что он продлится до сентября. Если вам нужно протестировать его с данными за август, просто измените ADD_MONTHS параметр на -2 вместо -1 . ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ