pl sql 过程中的日期格式传递到字符串中

Date format in pl sql procedure pass into a string

我无法将正确的日期格式传递给我的程序。我确实在论坛上搜索但没有找到解决方案。当我提取字符串中的值时,我得到以下结果

select *
  from (select a.col1,
               a.col2,
               a.col3,
               dense_rank() over(order by a.col2) as TheRank,
               round((count(*) over(order by a.col2)), 1) as UniqueRank
          from abt_t a
         where a.col4 >= to_date(05 - JAN - 98, 'YYYY-MM-DD')
           and a.col4 <= 05 - JAN - 98
           and (a.col2 <= '15:59' and a.col2 >= '09:30')
         order by 1 asc, 2)
 where TheRank = 390
   and UniqueRank = 05 - JAN - 98

值 05 - JAN - 98 与我启动的值完全不同 p_start_dt date:= to_date('1998-01-05', 'YYYY-MM-DD');

我试过了

这是我的程序:

create or replace procedure GET_VOL_OPTION_test is

BEGIN
  DECLARE
  -- Local variables here
w_sqlcode                           number := 0;
w_sqlerrm                            char(500) := '';
query_str VARCHAR2(2000);
TYPE cur_typ IS  ref CURSOR;
V_TABLE varchar2(200) :=NULL; 
c cur_typ;
inv_num NUMBER;
exp_dt date;
Curr_dt date;
inv_amt varchar2(5);
p_start_dt date:= to_date('1998-01-05', 'YYYY-MM-DD');
CURSOR CUR_OVRDDEF_PARAM_EN IS
select tname from OPT_TBL_NM_2015_T  order by tname;

BEGIN

  FOR XX IN CUR_OVRDDEF_PARAM_EN LOOP
    BEGIN
      ----


 query_str := 'select * from (select a.col1, a.col2, a.col3,' ||
              'dense_rank() over (order by a.col2) as TheRank,' ||
              'round((count(*) over (order by a.col2)),1) as UniqueRank ' ||
              /*'from '|| p_stock  || ' a' ||*/
              'from abc_t a' ||
              ' where a.col4 >=  to_date(' || to_char(p_start_dt)  || ', ''YYYY-MM-DD'')' || ' and ' || 'a.col4 <= ' || p_start_dt ||
              ' and (a.col2 <= ''15:59'' and a.col2 >= ''09:30'')' ||
              'order by 1 asc,2)' ||
              'where TheRank = 390 and UniqueRank = ' || p_start_dt;    
    OPEN c FOR query_str ;
    LOOP
        FETCH c INTO inv_num, exp_dt, curr_dt, inv_amt;

        EXIT WHEN c%NOTFOUND;
        -- process row here

    END LOOP;

   /*  EXCEPTION
         WHEN OTHERS THEN NULL;
       END;*/

      EXCEPTION
          WHEN OTHERS THEN 
            w_sqlcode := SQLCODE;
            w_sqlerrm := SQLERRM;
        END;
    END LOOP;

    COMMIT;
  END;
  END;

我正在使用oracle 12,如果您需要更多信息,请不要犹豫。

此致,

克里斯蒂安

这是您创建日期比较的行:

' where a.col4 >=  to_date(' || to_char(p_start_dt)  || ', ''YYYY-MM-DD'')' || ' and ' || 'a.col4 <= ' || p_start_dt ||

你会得到

where a.col4 >= to_date(05 - JAN - 98, 'YYYY-MM-DD') and a.col4 <= 05 - JAN - 98

显然您的标准日期格式是 'DD - MON - RR'。为什么你甚至依赖一个设置?您应该在to_char中指定格式,例如:

to_char(p_start_dt, 'YYYY-MM-DD') 

而不是使用 to_char(p_start_dt)p_start_dt(两者相同;使用默认设置将日期转换为字符串)。

您还遗漏了引号。正确的语法应该是:

' where a.col4 >= to_date(''' || to_char(p_start_dt, 'YYYY-MM-DD')  || ''', ''YYYY-MM-DD'') and ' ||
       'a.col4 <= to_date(''' || to_char(p_start_dt, 'YYYY-MM-DD')  || ''', ''YYYY-MM-DD'')' ||

或更简单的 ISO 日期文字:

' where a.col4 >= date ''' || to_char(p_start_dt, 'YYYY-MM-DD') || ''' and ' ||
       'a.col4 <= date ''' || to_char(p_start_dt, 'YYYY-MM-DD') || '''' ||

当然和

一样
' where a.col4 = date ''' || to_char(p_start_dt, 'YYYY-MM-DD') || '''' ||

问题是您在调用 to_char(p_start_dt) 时没有格式掩码(或者稍后,在日期上使用字符串连接)并且 Oracle 将使用 NLS_DATE_FORMAT 会话将日期转换为字符串范围。正如您所发现的,这可能设置为 DD-MON-YY 并导致您出现问题。如果您要将日期转换为字符串并将其嵌入到动态 SQL 中,那么您需要指定转换的格式掩码(即 TO_CHAR( p_start_date, 'YYYY-MM-DD' ));然而,更好的解决方案是:

在你的动态中使用绑定变量SQL,然后在你打开光标时传入日期:

DECLARE
  -- Local variables here
  w_sqlcode  number := 0;
  w_sqlerrm  char(500) := '';
  query_str  VARCHAR2(2000)
               := 'select * from (select a.col1, a.col2, a.col3,' ||
                  'dense_rank() over (order by a.col2) as TheRank,' ||
                  'count(*) over (order by a.col2) as UniqueRank' ||
                  ' from abc_t a' ||
                  ' where a.col4 BETWEEN :start_dt AND :start_dt' ||
                  ' and (a.col2 <= ''15:59'' and a.col2 >= ''09:30'')' ||
                  'order by 1 asc,2)' ||
                  'where TheRank = 390 and UniqueRank = :start_dt';
  c          SYS_REFCURSOR;
  inv_num    NUMBER;
  exp_dt     DATE;
  Curr_dt    DATE;
  inv_amt    VARCHAR2(5);
  p_start_dt DATE := DATE '1998-01-05';
  CURSOR CUR_OVRDDEF_PARAM_EN IS
    select tname from OPT_TBL_NM_2015_T  order by tname;
BEGIN
  FOR XX IN CUR_OVRDDEF_PARAM_EN LOOP
    BEGIN
      OPEN c FOR query_str USING p_start_dt;
      LOOP
        FETCH c INTO inv_num, exp_dt, curr_dt, inv_amt;

        EXIT WHEN c%NOTFOUND;
        -- process row here
      END LOOP;
    EXCEPTION
      WHEN OTHERS THEN 
        w_sqlcode := SQLCODE;
        w_sqlerrm := SQLERRM;
    END;
  END LOOP;
  COMMIT;
END;
/

此外,您为什么要将 UniqueRank 与日期值进行比较?