问题:为什么我的decode
语句未返回我需要的值?
我注意到的第一件事是日期格式错误,因为Toad在DD/MM/RR
中分配了日期,并且我试图将其与DD/MM/YYY
进行比较。因此,我尝试在过程开始时设置nls
格式。
请问如何解决这个问题?
请在下面找到代码
declare
vMES_ACTUAL NUMBER(6);
vMES_ANT NUMBER(6);
vTRIM_ANT NUMBER(6);
vTRIM_ACT NUMBER(6);
vMES_BASE NUMBER(6);
vMES_INTA NUMBER(6);
vMES_ULT_DIC NUMBER(6);
vFECHA DATE;
vMES_CURSO NUMBER(6);
----------
vFECHA1 DATE;
vFECHA2 DATE;
vFECHA3 DATE;
vFECHA4 DATE;
vFECHA5 DATE;
vFECHA6 DATE;
vNUM_DIAS_CARGA NUMBER;
vSEMANAS_TRANSC NUMBER;
var_mes1 number(6);
var_mes2 number(6);
var_mes3 number(6);
----------
FEC_VAR_DIA VARCHAR2(10);
Pmes number(6):=201810;
begin
execute immediate 'alter session set nls_date_format = ''DD/MM/YYYY''';
SELECT Pmes INTO vMES_CURSO FROM DUAL;
/* Ultimos 6 dias de carga */
SELECT MAX(ID_FECHA) INTO vFECHA1
FROM CAP_BPP_FECHA_VAR6DIAS;
SELECT NVL(MAX(ID_FECHA),vFECHA1) INTO vFECHA2
FROM CAP_BPP_FECHA_VAR6DIAS
WHERE ID_FECHA < vFECHA1;
SELECT NVL(MAX(ID_FECHA),vFECHA2) INTO vFECHA3
FROM CAP_BPP_FECHA_VAR6DIAS
WHERE ID_FECHA < vFECHA2;
SELECT NVL(MAX(ID_FECHA),vFECHA3) INTO vFECHA4
FROM CAP_BPP_FECHA_VAR6DIAS
WHERE ID_FECHA < vFECHA3;
SELECT NVL(MAX(ID_FECHA),vFECHA4) INTO vFECHA5
FROM CAP_BPP_FECHA_VAR6DIAS
WHERE ID_FECHA < vFECHA4;
SELECT NVL(MAX(ID_FECHA),vFECHA5) INTO vFECHA6
FROM CAP_BPP_FECHA_VAR6DIAS
WHERE ID_FECHA < vFECHA5;
/* Hace el conteo de los numeros de dias */
SELECT COUNT(*)
INTO vNUM_DIAS_CARGA
FROM CAP_BPP_FECHA_VAR6DIAS;
EXECUTE IMMEDIATE ('TRUNCATE TABLE CAP_BPP_CTA_VAR_PASO');
INSERT /*+ NOLOGGING */ INTO CAP_BPP_CTA_VAR6DIAS_PASO(
ID_CLIENTE, ID_CONTRATO, ID_MES, ID_PRODUCTO, ID_SUBPRODUCTO,
ID_DIVISA,
SDO_PUNT_DIA_1)
SDO_PUNT_DIA_2,
SDO_PUNT_DIA_3,
SDO_PUNT_DIA_4,
SDO_PUNT_DIA_5,
SDO_PUNT_DIA_6)
SELECT BT.ID_CLIENTE, BT.ID_CONTRATO, vMES_CURSO, BT.ID_PRODUCTO,
BT.ID_SUBPRODUCTO,BT.ID_DIVISA,
CASE WHEN vNUM_DIAS_CARGA < 1 THEN 0 ELSE NVL(SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/YYYY'),vFECHA1,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_1
CASE WHEN vNUM_DIAS_CARGA < 2 THEN 0 ELSE NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA2,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_2,
CASE WHEN vNUM_DIAS_CARGA < 3 THEN 0 ELSE NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA3,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_3,
CASE WHEN vNUM_DIAS_CARGA < 4 THEN 0 ELSE NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA4,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_4,
CASE WHEN vNUM_DIAS_CARGA < 5 THEN 0 ELSE NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA5,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_5,
CASE WHEN vNUM_DIAS_CARGA < 6 THEN 0 ELSE NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA6,SDO_PUNTUAL)),0) END SDO_PUNT_DIA_6
FROM CAP_BPP_CTA_FTE_DIA BT
WHERE BT.FECHA_INFORMACION IN (vFECHA1, vFECHA2, vFECHA3, vFECHA4, vFECHA5, vFECHA6)
GROUP BY ID_CLIENTE, ID_CONTRATO, vMES_CURSO, ID_PRODUCTO, BT.ID_SUBPRODUCTO, ID_DIVISA;)
COMMIT;
end;
答案 0 :(得分:0)
您当前正在这样做:
NVL(SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/YYYY'),vFECHA1,SDO_PUNTUAL)),0)
评论中讨论的
不应将TO_DATE()
应用于已经是日期的内容,因此您要么需要:
NVL(SUM(DECODE(BT.FECHA_INFORMACION,vFECHA1,SDO_PUNTUAL)),0)
在进行比较时,或者FECHA_INFORMACION
具有除午夜以外的时间部分的值:
NVL(SUM(DECODE(TRUNC(BT.FECHA_INFORMACION),vFECHA1,SDO_PUNTUAL)),0)
TRUNC()
函数默认将日期值的时间部分设置为午夜,因此一天中的所有值都将获得相同的datetime值。如果ID_FECHA
也有非午夜时间,那么您也可以截断这些变量,尽管从联系人看来似乎不太像这样:
NVL(SUM(DECODE(TRUNC(BT.FECHA_INFORMACION),TRUNC(vFECHA1),SDO_PUNTUAL)),0)
您也可以在解码中将默认值设置为零,但是在这种情况下,应该没有太大的区别。
没有TO_DATE()
及其隐式TO_CHAR()
的NLS设置无关紧要,因为您正在将日期与其他日期进行比较。 Oracle使用内部表示形式,它与客户端如何将日期显示为字符串无关。
您可能对此也有疑问:
WHERE BT.FECHA_INFORMACION IN (vFECHA1, vFECHA2, vFECHA3, vFECHA4, vFECHA5, vFECHA6)
因为那也只能完全匹配午夜。您也可以截断它:
WHERE TRUNC(BT.FECHA_INFORMACION) IN (vFECHA1, vFECHA2, vFECHA3, vFECHA4, vFECHA5, vFECHA6)
再次假设FECHA_INFORMACION
具有非午夜时间,并且变量都位于午夜。这样可以防止使用FECHA_INFORMACION
,但您可以改为比较多个范围。先看看能否解决问题。
答案 1 :(得分:0)
我以最简单的方式解决问题,也许我的问题的表达方式不正确,因为我只想匹配日期格式以从查询中获取数据。感谢那些试图帮助的人。这就是我解决的方法。
INSERT /*+ NOLOGGING */ INTO CAP_BPP_CTA_VAR6DIAS_PASO(
ID_CLIENTE, ID_CONTRATO, ID_MES, ID_PRODUCTO, ID_SUBPRODUCTO, ID_DIVISA,
SDO_PUNT_DIA_1,
SDO_PUNT_DIA_2,
SDO_PUNT_DIA_3,
SDO_PUNT_DIA_4,
SDO_PUNT_DIA_5,
SDO_PUNT_DIA_6)
SELECT /*+ PARALLEL(BT,4) */
ID_CLIENTE, ID_CONTRATO, vMES_CURSO, ID_PRODUCTO, BT.ID_SUBPRODUCTO,ID_DIVISA,
CASE WHEN vNUM_DIAS_CARGA < 1 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA1,SDO_PUNTUAL)) END SDO_PUNT_DIA_1,
CASE WHEN vNUM_DIAS_CARGA < 2 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA2,SDO_PUNTUAL)) END SDO_PUNT_DIA_2,
CASE WHEN vNUM_DIAS_CARGA < 3 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA3,SDO_PUNTUAL)) END SDO_PUNT_DIA_3,
CASE WHEN vNUM_DIAS_CARGA < 4 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA4,SDO_PUNTUAL)) END SDO_PUNT_DIA_4,
CASE WHEN vNUM_DIAS_CARGA < 5 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA5,SDO_PUNTUAL)) END SDO_PUNT_DIA_5,
CASE WHEN vNUM_DIAS_CARGA < 6 THEN 0 ELSE SUM(DECODE(TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR'),vFECHA6,SDO_PUNTUAL)) END SDO_PUNT_DIA_6
FROM CAP_BPP_CTA_FTE_DIA BT
WHERE TO_DATE(BT.FECHA_INFORMACION,'DD/MM/RR') IN (vFECHA1, vFECHA2, vFECHA3, vFECHA4, vFECHA5, vFECHA6)
GROUP BY ID_CLIENTE, ID_CONTRATO, vMES_CURSO, ID_PRODUCTO, BT.ID_SUBPRODUCTO, ID_DIVISA;
COMMIT;