database - 在plsql中执行带有null的日期字段
问题描述
您好,我有一个程序和问题。此过程用于提取数据,然后将它们插入到一个表中。我想要做的是,如果 pid_billdate 为空,则在执行过程时,它应该使用前几个月的最后一天作为参数。我已经在程序定义行中尝试过,但没有正确解决。那么我怎样才能做出这种改变呢?我需要将此控件添加到过程中。
我的第二个问题是如何测试它(我的意思是如何输入空值?)
BEGIN
GPU_DATA_EXTRACTOR_TEST(); -- or is it should be GPU_DATA_EXTRACTOR_TEST(null) ?
END;
我愿意接受任何建议。注意:我只有大约 2021 年 8 月 31 日的记录,所以我已经尝试将第一行中的值 -1 更改为 -2 进行测试,但没有插入到 GPU_INV_TEST 表中。我的程序脚本如下,从现在开始谢谢你。
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
正如你所说
没有正常工作
我认为没有行被插入到gpu_inv_test
表中。有两种可能:
- 任何一个游标
select
都没有返回任何东西(所以循环根本没有执行) select
s inforall
没有返回任何内容(因此,尽管游标获取了一些行,但select
s 没有返回任何要插入到表中的行。
我们无法真正测试它,因为我们没有您的表(并且您在FROM
子句中使用了一堆),所以应该由您来测试它。
至于你的第二个问题:两个选项都可以。
推荐阅读
- python - 怎么做,每行分组并在python中获取上一个日期的平均值
- android - sh.CommandNotFound: ./compile.sh Buildozer 和 KivyMD 错误
- jmeter - jmeter有什么方法可以在参数内传递参数吗?
- c++ - 以错误的方式使用#define 来调用函数。为什么?
- postgresql - 双端口转发kubernetes + docker
- java - 打印机:问题将文本文件的内容保存在一维数组中
- java - Firebase 实时数据库未设置值 - Android
- android - 如何在flutter_local_notification中创建无限的id?
- java - 无法在本地主机上运行项目 spring mvc
- bash - Bash 脚本 shell 输入变量