'选择' preparedStatement wih Timestamp返回总是为空的RecordSet

时间:2015-09-20 09:30:22

标签: java oracle jdbc prepared-statement recordset

我尝试使用JDBC瘦驱动程序从ORACLE数据库表中检索记录。 准备好的声明我使用: (1)

SELECT (t1.LOGGED_TIME - ?) AS TDIFF, t1.ID, t1.STATUS, t1.LOGGED_TIME, t1.SERVER_TIME 
        FROM table_1 t1 
        WHERE (
          ((t1.LOGGED_TIME - ?) <= INTERVAL '10' DAY) 
          AND ((t1.LOGGED_TIME - ?) >= INTERVAL '-10' DAY)) 
        ORDER BY t1.LOGGED_TIME DESC

其中t1.LOGGED_TIME表示时间戳列。每三个参数都是使用

设置的相同时间戳
java.sql.Timestamp controlTime = Timestamp.valueOf("2014-08-15 03:52:00");

lookupTime.setTimestamp(1, controlTime);
lookupTime.setTimestamp(2, controlTime);
lookupTime.setTimestamp(3, controlTime);

执行代码工作正常 - 不显示异常或警告。然而,结果集由

返回
rs =  lookupTime.executeQuery();

是空的。

将查询设置为 (2)

SELECT (t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) AS TDIFF, t1.ID, t1.STATUS, t1.LOGGED_TIME, t1.SERVER_TIME 
FROM table_1 t1 
WHERE (
  ((t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) <= INTERVAL '10' DAY) 
  AND ((t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) >= INTERVAL '-10' DAY)) 
ORDER BY t1.LOGGED_TIME DESC

返回预期的数据。 当我查询例如来自同一个表的另一列的字符串和一个准备好的语句,结果是可以的。

我在这里失踪了什么?重点在哪里?有什么想法吗?

说得清楚:关键是不要在(2)中找出一种错误的日期/时间格式转换。这将始终导致oracle错误消息,并且可以轻松修复。

问题是:为什么在没有任何错误通知的情况下保持preparedStatement(1)返回的RecordSet为空(=不是单个记录)?如果时间戳格式有任何错误,为什么没有错误或警告?

1 个答案:

答案 0 :(得分:0)

检查您的TO_TIMESTAMP格式:

TO_TIMESTAMP('2014-08-15 03:52',
               'dd.mm.yy hh24:mi')

Aug. 14, 2015,而不是Aug. 15, 2014

<强>更新

实际上,我在尝试那个时遇到以下错误:

ORA-01843: not a valid month
01843. 00000 -  "not a valid month"

<强> UPDATE2

Java Timestamp映射到Oracle DATE数据类型,而不是TIMESTAMP。不知道这是否有所作为,但您可以尝试TO_TIMESTAMP(?)

但是,我会更改查询以允许在LOGGED_TIME上使用潜在索引:

SELECT ID, STATUS, LOGGED_TIME, SERVER_TIME
  FROM table_1
 WHERE LOGGED_TIME BETWEEN ? AND ?
 ORDER BY LOGGED_TIME DESC

然后用Java完成所有数学运算:

Timestamp controlTime = Timestamp.valueOf("2014-08-15 03:52:00");
Calendar cal = Calendar.getInstance();
cal.setTime(controlTime);
cal.add(Calendar.DAY_OF_MONTH, -10);
lookupTime.setTimestamp(1, new Timestamp(cal.getTimeInMillis()));
cal.setTime(controlTime);
cal.add(Calendar.DAY_OF_MONTH, 10);
lookupTime.setTimestamp(2, new Timestamp(cal.getTimeInMillis()));
try (ResultSet rs = lookupTime.executeQuery()) {
    while (rs.next()) {
        long tdiffInSeconds = (rs.getTimestamp("LOGGED_TIME").getTime() - controlTime.getTime()) / 1000;
        // other code
    }
}