如何绑定动态查询的日期

时间:2013-12-20 13:10:57

标签: sql plsql

我正在开发一个脚本,该脚本执行动态构建查询并检查其中的日期。 这不是实际的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,但到目前为止我无法得到理想的结果。

我无法改变查询是动态构建的事实。

2 个答案:

答案 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。困难的部分可能是获得正确数量的单引号。