Переменные не сравниваются должным образом - PullRequest
0 голосов
/ 26 октября 2018

Проблема : почему мой оператор decode не возвращает нужное мне значение?

Первое, что я заметил, это то, что формат даты был неправильным, потому что жаба назначала его в 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;

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Я решаю проблему самым простым способом, может быть, мой вопрос был сформулирован неправильно, потому что я хотел только соответствовать формату даты, чтобы получить данные из запроса. Спасибо ребятам, которые пытались помочь. Это способ, которым я решил это.

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;
0 голосов
/ 26 октября 2018

Вы сейчас делаете это:

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, но вместо этого вы можете переключиться для сравнения нескольких диапазонов. Посмотрим, решит ли это проблему в первую очередь.

...