在Oracle数据库中使用JdbcTemplate插入时间戳(ORA-01858)

4

我已经阅读了很多关于这个错误的资料,但仍然没有找到错误。

我正在使用JdbcTemplate在某个表中插入一行,其中包含一些时间戳列。我很确定时间戳是问题所在,因为如果删除插入的时间戳列,则可以正常工作)

我的代码:

        private static final String INSERT_CITAS = "INSERT INTO CITAS (" 
        + "idCita, idServicio, " + "fechaCita, "
        + "idEstado, idUsuarioInicial) " + "VALUES (?, ?, ?, ?, ?)";

        Object[] params = {
                idCita,
                citaQuenda.getIdServicio(),
                getDateToDBFormat(citaQuenda.getFechaCita()),
                ESTADO_INICIAL,
                USUARIO_INICIAL };

        String queryCitas = INSERT_CITAS;

        super.getJdbcTemplate().update(queryCitas, params);


        protected String getDateToDBFormat(Date fechaCreacion){
        return  "TO_TIMESTAMP('" + 
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fechaCreacion)
                    + "', 'yyyy-mm-dd hh24:mi:ss')" ;
        }

接下来出现了以下错误:

    org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO citas_55 (idCita, idServicio, fechaCita, idEstado, idUsuarioInicial) VALUES (?, ?, ?, ?, ?)];
    ORA-01858: a non-numeric character was found where a numeric was expected

我尝试在一些 SQL 编辑器中执行 sql 语句时成功了,所以我更加困惑了。

我的参数是:[461, 100, TO_TIMESTAMP('2015-01-28 00:00:01', 'yyyy-mm-dd hh24:mi:ss'), 1, 8888]。这实际上是有效的。

    INSERT INTO citas (idCita, idServicio, fechaCita, idEstado, idUsuarioInicial) VALUES (457, 100, TO_TIMESTAMP('2015-01-28 00:00:01', 'yyyy-mm-dd hh24:mi:ss') , 1, 8888);

非常感谢您的帮助,有任何问题请联系我们。提前致谢!


我不熟悉这个模板,但是更新是否使用表元数据来决定设置什么类型的参数 - 因此它将尝试使用您的字符串值进行setTimestamp(),可能会引入隐式转换? - Alex Poole
一个DATE类型和一个TIMESTAMP类型是不同的。你的例子展示了TO_DATE和TO_TIMESTAMP,请展示表定义。 - OldProgrammer
只是一个小错误,但两种方法都可以正常工作... - elcadro
文档中说:“将其留给PreparedStatement猜测相应的SQL类型”,所以可能不像我想象的那么随意……所以,为什么不将它作为时间戳传递呢? - Alex Poole
谢谢Alex,你也是正确的。 - elcadro
2个回答

9
不要将日期/时间戳和字符串来回转换。只需将java.sql.Timestamp实例作为参数传递即可:
Object[] params = {
         idCita,
         citaQuenda.getIdServicio(),
         new java.sql.Timestamp(citaQuenda.getFechaCita()),
         ESTADO_INICIAL,
         USUARIO_INICIAL };

String queryCitas = INSERT_CITAS;
super.getJdbcTemplate().update(queryCitas, params);

3

我会冒昧猜测问题所在。getDateToDBFormat()方法返回的是一个包含文本“TO_TIMESTAMP(...)”的字符串类型,而不是日期或时间戳参数。这是一个字符串参数。你需要做的是:

  1. Remove the TO_TIMESTAMP stuff from getDateToDBFormat() and have it just return the formatted DATE/TIME value (the format you show is not an oracle timestamp, but a DATE type).

  2. change your insert to:

    "INSERT INTO CITAS ... VALUES (?, ?, TO_DATE(?,?) , ?, ?)"
    

TO_DATE函数的参数应该是从getDateToDBFormat()返回的值,第二个参数是日期格式掩码。但是,你不可以直接绑定Java Date类型(或jdbc sql的等价类型)来解决这个问题吗?

那应该行得通。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接