我正在开发一个脚本,该脚本执行动态构建查询并检查其中的日期。 这不是实际的scipt只是SSCCE,以显示我的问题:
DECLARE
lv_query VARCHAR2(500);
lv_date DATE;
BEGIN
lv_date := &cutomDate;
lv_query := 'select * from executionlog e
where e.execution_timestamp > ' || lv_date;
dbms_output.put_line(lv_query);
EXECUTE IMMEDIATE(lv_query);
END;
当我给出一个自定义日期例如:to_date('01011987','ddmmyyyy')
我得到以下字符串作为我的查询:
从执行日志中选择* 其中e.execution_timestamp> 01-JAN-87
我收到以下错误:
ORA-00904错误:“JAN”:标识符无效。
我理解这个查询无法正确执行,因为e.execution_timestamp是一个日期而01-JAN-87是一个Varchar2。
如何将01-JAN-87转换回日期?我已经玩过to_date
,但到目前为止我无法得到理想的结果。
我无法改变查询是动态构建的事实。
答案 0 :(得分:2)
使用绑定变量而不是连接:
DECLARE
lv_query VARCHAR2(500);
lv_date DATE;
BEGIN
lv_date := &cutomDate;
lv_query := 'select * from executionlog e
where e.execution_timestamp > :pDate';
dbms_output.put_line(lv_query);
EXECUTE IMMEDIATE lv_query USING lv_date;
END;
您可以在代码中提示输入字符串并TO_DATE,而不是让用户使用TO_DATE函数:
DECLARE
lv_query VARCHAR2(500);
lv_date DATE;
BEGIN
lv_date := TO_DATE(&cutomDate,'DDMMYYYY');
lv_query := 'select * from executionlog e
where e.execution_timestamp > :pDate';
dbms_output.put_line(lv_query);
EXECUTE IMMEDIATE lv_query USING lv_date;
END;
现在,用户只需在提示时键入01011987
。
答案 1 :(得分:0)
我有类似的情况。区别在于我在sql server上使用openquery连接到oracle。这意味着我必须向oracle发送一个sql字符串,类似于你正在做的事情。我找到了格式:
{ts 'yyyy-mm-dd hh:mm:ss'}
会给出好的结果。我写了一个返回此函数的函数:
select @StringOut = '{ts ''''' + convert(varchar(20), @DateIn, 20) + ''''' }';
在您的情况下,您必须使用适当的掩码使用to_char。困难的部分可能是获得正确数量的单引号。