我无法将正确的日期格式传递给我的程序。我在论坛上搜索但没有找到解决方案。当我在字符串中提取值时,我得到以下结果
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.如果您需要更多信息,请不要犹豫。
此致
基督教
答案 0 :(得分:1)
问题是您在没有格式掩码的情况下调用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
与日期值进行比较?
答案 1 :(得分:0)
这是您创建日期比较的行:
' 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&#39;”。为什么你甚至依赖于环境?您应该在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') || '''' ||