变量没有正确比较

Variables doesn't compare properly

问题:为什么我的 decode 语句没有 return 我需要的值?

我注意到的第一件事是日期格式错误,因为蟾蜍在 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;

您目前正在这样做:

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() 函数默认将日期值的时间部分设置为午夜,因此一天的所有值都具有相同的日期时间值。如果 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,但您可以改为比较多个范围。先看看是否能解决问题。

我用最简单的方法解决了这个问题,也许我的问题表述有误,因为我只想匹配日期格式以从查询中获取数据。感谢那些试图提供帮助的人。这就是我解决它的方式。

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;