使用预准备语句在Oracle中生成日期

时间:2014-04-10 23:27:00

标签: java oracle date prepared-statement

我这里有一个有趣的问题。我正在尝试使用Oracle to_char命令生成XML日期。当我使用PL / SQL执行此操作时,一切正常:

18:05:54 SQL> select to_char(sysdate, 'yyyy-mm-dd"T"hh24:mi:ss".000Z"') from dual;

TO_CHAR(SYSDATE,'YYYY-MM-DDT
---------------------------------------------------------------------------
2014-04-10T23:09:50.000Z

然而,当我将该日期格式放入Java程序并使用预准备语句时,它会抛出一个非常奇怪且毫无意义的错误"错过IN OUT参数在index :: 6"这很奇怪,因为只有5个参数。我知道它是日期格式,因为如果我改变格式,命令工作正常。

这是我的日期格式字符串和有效的字符串:

private static final String XML_DATE = ", 'YYYY-MM-DD\"T\"HH24:MM:SS\"Z\")";  <-- BROKEN

private static final String XML_DATE = ", 'YYYY-MM-DD HH24:MM:SS')";  <-- Working

您可能会注意到我需要转义引号以将它们保留在字符串中。

一些额外的信息。该字符串从主预准备语句中插入。这就是为什么它看起来有点滑稽。所以我的SQL语句的每一行都是这样的:

    "   NVL(to_char(flt.my_date_dtm" + XML_DATE + ",'') my_date_dtm, " +

抛出的实际错误是:

java.sql.SQLException: Missing IN or OUT parameter at index:: 6

再次,这很奇怪,因为有5个参数。任何人都有任何想法,为什么它这样做?

1 个答案:

答案 0 :(得分:1)

你在“破碎”中错过了一个结束的单引号。之一:

private static final String XML_DATE = ", 'YYYY-MM-DD\"T\"HH24:MM:SS\"Z\")";
                                                                         ^

您在破损和工作版本中也将MI更改为MM。所以它应该是:

private static final String XML_DATE = ", 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')";

不确定您是否故意遗漏了.000部分。

我认为这会解析解析并且稍后在构造的字符串中生成冒号会被解释为绑定变量。因为你没有得到一个缺失引用错误,你可能在最后的字符串中使用这种格式两次(或偶数次,无论如何),所以总的来说你最终得到了有效的字符串。有点长 - 没有意义,但至少有平衡的引用......

当我看到这样的错误并且无法立即发现问题时,我通常会将最终字符串写入控制台并尝试通过SQL * Plus运行,这往往会使问题更加明显。