在plsql中执行带空的日期字段

Executing date field with null in plsql

您好,我有一个程序和相关问题。此过程用于提取数据然后将它们插入一个 table。我想做的是,如果 pid_billdate 为 null,则在执行该过程时,它应该使用前几个月的最后一个 dasy 作为参数。我已经在过程定义行中尝试过,但没有正确解决。那么我怎样才能做出这个改变呢?我需要将此控件添加到程序中。

我的第二个问题是如何测试它(我的意思是如何输入空值?)

BEGIN
   GPU_DATA_EXTRACTOR_TEST(); -- or is it should be GPU_DATA_EXTRACTOR_TEST(null) ?
END;

我愿意接受任何建议。 注意:我只有大约 8/31/2021 的记录,所以我已经尝试将第一行的值 -1 更改为 -2 以进行测试,但没有插入到 GPU_INV_TEST table。 下面是我的程序脚本,谢谢大家。

    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;

默认值计算正确:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> SELECT LAST_DAY (ADD_MONTHS (TRUNC (SYSDATE), -1)) result FROM DUAL;

RESULT
----------
30.09.2021

SQL>

唯一使用pid_billdate的地方是游标的select语句:

   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;          --> here

正如你所说

didn't worked out properly

我假设没有行被插入 gpu_inv_test table。有两种可能:

  • 任一游标的 select 都没有 return 任何东西(所以循环根本没有执行)
  • forall 中的
  • selects 没有 return 任何东西(因此,尽管游标获取了一些行,但 selects 没有 return 要插入到 table.
  • 中的任何行

我们无法真正测试它,因为我们没有您的 table(您在 FROM 子句中使用了一堆),所以应该由您来测试。


关于你的第二个问题:两个选项都可以。