【问题标题】:JDBC: How can I query by time in Oracle?JDBC:如何在 Oracle 中按时间查询?
【发布时间】:2009-08-14 09:05:48
【问题描述】:

我有这个 JDBC SQL 查询:

select *
from table
where TX_DATE = {d '2009-01-05'} and TX_TIME = {t '15:23:39'}

这会返回一些行。请注意,由于 Oracle 没有 TIME 类型,因此两列都是 DATE 类型。

但是当我使用 JDBC 参数时它失败了:

select *
from table
where TX_DATE = ? and TX_TIME = ?

第一个参数是new java.sql.Date(...),第二个参数是new java.sql.Time(...)。我将两个参数都打印到标准输出,它们看起来不错,所以值是正确的。但我没有得到任何行。为什么? {t '15:23:39'}new java.sql.Time() 有什么区别?

[编辑] 这是填写PreparedStatement的代码:

public static void setParameters (final PreparedStatement stmt,
        final Object... param)
{
    for (int i=0; i<param.length; i++)
    {
        Object debug = param[i];
        String type = null;

        if (param[i] == null)
            stmt.setString(i+1, null);
        else if (param[i] instanceof java.sql.Time)
             stmt.setTime (i+1, (java.sql.Time)param[i]);

我在setTime() 中设置了一个断点,它会被调用。 param[1].toString() 打印出15:23:39,所以我知道这个值是正确的。

我的猜测是,由于Oracle没有TIME类型,所以驱动程序中存在错误,并且没有忽略时间的DATE部分。

如果我在整张桌子上使用select *,我会得到

TX_DATE     TX_TIME
2009-01-08  2009-08-01

如您所见,默认情况下时间列被视为日期。如果我使用TO_CHAR(TX_TIME, 'HH24:MI:SS'),我会得到:

TX_DATE     TX_TIME
2009-01-08  15:23:39

2009-08-01 来自哪里?

【问题讨论】:

    标签: java oracle jdbc


    【解决方案1】:

    Oracle 没有时间的 Java 类型。 java.sql.Time 类映射到 oracle.sql.DATE 类,即使在最新的驱动程序中也是如此。 Documentation Here 你应该做的是让 TX_TIME 的“天”部分成为一些标准值(比如 1970-01-01)。然后,您可以使用静态“天”查询此列,并让时间按预期工作。

    根据您使用的 Oracle 驱动程序的版本,对 Oracle DATE 列类型的 java.sql.Date 和 java.sql.Timestamp 的处理是不同的。查看JDBC FAQ 了解更多信息。祝你好运!

    public static void setParameters (final PreparedStatement stmt,
        final Object... param)
    {
      for (int i=0; i<param.length; i++)
      {
          Object debug = param[i];
          String type = null;
    
          if (param[i] == null)
            stmt.setString(i+1, null);
          else if (param[i] instanceof java.sql.Time) 
          {
            stmt.setTime (
              i+1, 
              java.sql.Timestamp.valueof("1970-01-01 " + param[i] + ".000000000")
             );
          }
    

    【讨论】:

    • 谢谢;如果我没有指定一个而不是“当月的第一天”,我不知何故期望 Oracle 会使用相同的“天”部分。
    【解决方案2】:

    我假设您在此使用PreparedStatement

    PrepapredStatement stmt = conn.prepareStatement(
                   "select * from table where TX_DATE = ? and TX_TIME = ?")
    stmt.setDate(1, new java.sql.Date(myDate.getTime));
    stmt.setTimestamp(2, new java.sql.Timestamp(myDate.getTime));
    
    ResultSet rs = stmt.executeQuery();
    

    【讨论】:

    • 正如我所写,我使用的是 java.sql.Time,而不是 java.sql.Timestamp。
    • 我使用 SimpleDateFormat.parse() 初始化时间,格式为“HH:mm:ss”,值为“15:23:39”。
    • 您能否发布您的实际代码。很难调试我看不到的代码!您是否使用PreparedStatement 并按照我所说的设置参数(尽管有一段时间)?您是否尝试过使用时间戳,或者只是使用日期位来查看是否有效?
    • 查看我的编辑;我的猜测是,由于 Oracle 没有真正的“TIME”类型,Oracle 驱动程序中存在错误。
    • 注意两列的类型都是DATE(因为Oracle中没有原生TIME类型)。
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 2018-05-23
    • 1970-01-01
    • 2011-12-20
    相关资源
    最近更新 更多