pl/sql - to_date 不适用于执行立即参数

Posted

技术标签:

【中文标题】pl/sql - to_date 不适用于执行立即参数【英文标题】:pl/sql - to_date not working with execute immediate parameter 【发布时间】:2011-06-04 02:18:07 【问题描述】:

我希望能够像这样执行下面的过程:

exec procname('29-JAN-2011');

过程代码是:

PROCEDURE procname(pardate VARCHAR2) IS

  vardate DATE := to_date(pardate, 'DD-MON-YYYY');
  SQLS VARCHAR2(4000);

BEGIN    

  SQLS := 'SELECT cola, colb
             FROM tablea 
            WHERE TRUNC(coldate) = TRUNC(TO_DATE('''||pardate||''',''DD/MON/YYYY''))';

  EXECUTE IMMEDIATE SQLS;

END;

一直报错:

ORA-00904:“JAN”:标识符无效。

它可以编译,但是当我运行这个命令时它会抛出错误:

EXEC procname('29-JAN-2011');

【问题讨论】:

这不是实际代码,对吧?它不会编译。 我知道这只是一个示例,但该过程是否必须是动态 SQL?它可以作为常规程序正常工作。 它需要是动态的,因为我要让它在运行时列名是未知的 【参考方案1】:

您声明了一个将输入参数转换为日期的变量:为什么不使用它?

此外,应用于日期的 TRUNC() 会删除时间元素。你在这里不需要它,因为你传递的值没有时间。

所以,你的代码应该是:

PROCEDURE procname(pardate VARCHAR2) IS

  vardate DATE := to_date(pardate, 'DD-MON-YYYY');
  SQLS VARCHAR2(4000)  := 'select cola, colb FROM tablea 
           WHERE TRUNC(coldate) = :1';

   l_a tablea.cola%type;
   l_b tablea.colb%type;
BEGIN    
  EXECUTE IMMEDIATE SQLS 
      into l_a, l_b
      using vardate;
END;  

使用绑定变量指定动态 SQL 语句并使用 USING 语法执行它的效率要高得多。请注意,我们仍然必须选择一些变量。

【讨论】:

附带说明,trunc() 可以避免使用索引而不是coldate。他可能会考虑使用 vardate, vardate 的技巧“...... where collat​​e between :1 and :2 + 0.99999”。【参考方案2】:

您在对to_date 的两次调用中使用了两种不同的表示法。我认为其中一个(第二个)是错误的。

【讨论】:

我的意思是,其中一个是 DD-MON-YYYY,另一个是 DD/MON/YYYY。输入使用破折号,而不是斜线,所以我认为第二个是错误的。 也可能是语言设置问题。您是否居住在 1 月不缩写为 JAN 的国家/地区?

以上是关于pl/sql - to_date 不适用于执行立即参数的主要内容,如果未能解决你的问题,请参考以下文章

立即执行一个立即执行的 pl/sql

pl/sql : 执行立即更新?

PL/SQL DDL 立即执行

PL/SQL - dbms 输出立即执行的结果

to_date 函数 pl/sql

pl/sql to_date