Sysdate为char而不是date

时间:2017-02-19 20:25:07

标签: sql oracle plsql

我有一个查询。

我有一个配置表AB,其中一行被标记为“sysdate-360”

col1 ||col2
AB   || sysdate-360
BC   || sysdate -2

当我编写一个程序来从我使用的配置表AB中获取日期值时。

    v_date varchar(20);
    cursor c1 as
    select col2 from AB;
    then 

    for ab_date in c1
    loop
    select ab_date.col2 into v_date from dual;
v_sql := 'delete from any_table where load_date <='||v_date;
execute immediate v_sql ;
commit;
    end loop;

程序已编译,但当我执行时,我遇到错误

ORA-01722:无效的号码 ORA-06512:在“程序”,第46行 ORA-06512:第1行 01722. 00000 - “无效号码” *原因:
*操作:

sysdate -360被视为char但不是日期,因为SYSDATE本身就是一个日期吗?

请帮忙。

3 个答案:

答案 0 :(得分:2)

如果只处理表达式SYSDATE +/- N,我建议修改配置表,如下所示

ID SYSDATE_OFFSET
-- --------------
AB           -360 
BC             -2 

所以你有一个sysdate的数字偏移量,可以这样查询:

select sysdate + (select SYSDATE_OFFSET from config where id = 'AB') s_360
from dual;

S_360           
-----------------
25.02.16 21:46:50 

所以你可以用上面的查询打开一个光标。

如果您无法更改表格 - 定义一个删除字符串sysdate并转换为数字的视图!

答案 1 :(得分:2)

这对我来说很好看。但为什么选择v_date?你从光标得到一个可以直接连接的字符串:

for ab_date in c1 loop
  v_sql := 'delete from any_table where load_date <=' || ab_date.col2;
  execute immediate v_sql ;
  commit;
end loop;

最后,这只是两个字符串'delete from any_table where load_date <=''sysdate-360'的连接,这使得'delete from any_table where load_date <= sysdate-360' - 正是您想要的SQL字符串。

(使用适当的列名称,例如date_expression而不是col2,效果会更好。)

更详细的解释:光标为您提供字符串'sysdate-360'。查询select ab_date.col2 into v_date from dual;只是v_date := ab_date.col2;。但是v_date是一个字符串吗?如果没有,则会出现转换错误,因为'sysdate-360'只是一个字符串,仅此而已。如果您希望DBMS看到该字符串包含'sysdate',它恰好是当前时间的系统变量的名称,然后神奇地转换它,那么您期望得到很多。

答案 2 :(得分:-1)

尝试使用to_date函数

TO_DATE(v_date)