简体   繁体   English

JDBC:如何在Oracle中按时间查询?

[英]JDBC: How can I query by time in Oracle?

I have this JDBC SQL query: 我有这个JDBC SQL查询:

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

This returns some rows. 这将返回一些行。 Note that, since Oracle has no TIME type, both columns are of type DATE. 请注意,由于Oracle没有TIME类型,因此两列均为DATE类型。

But it fails when I use JDBC parameters: 但是当我使用JDBC参数时它失败了:

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

where the first parameter is new java.sql.Date(...) and the second is new java.sql.Time(...) . 其中第一个参数是new java.sql.Date(...) ,第二个参数是new java.sql.Time(...) I print both parameters to stdout and they look good, so the values are correct. 我将两个参数都打印到stdout,它们看起来不错,因此值是正确的。 But I don't get any rows. 但是我没有任何行。 Why? 为什么? What's different between {t '15:23:39'} and new java.sql.Time() ? {t '15:23:39'}new java.sql.Time()什么区别?

[EDIT] Here is the code that fills the PreparedStatement : [编辑]这是填充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]);

I've set a breakpoint in setTime() and it gets called. 我在setTime()设置了一个断点,它被调用。 param[1].toString() prints 15:23:39 , so I know the value is correct. param[1].toString()打印15:23:39 ,所以我知道该值是正确的。

My guess is that since Oracle doesn't have a TIME type, there is a bug in the driver and the DATE part of the time is not ignored. 我的猜测是,由于Oracle没有TIME类型,因此驱动程序中存在一个错误,并且不会忽略DATE部分的时间。

If I use select * on the whole table, I get 如果我在整个表上使用select * ,我得到

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

As you can seem, the time column is treated like a date by default. 如您所见,默认情况下,时间列被视为日期。 If I use TO_CHAR(TX_TIME, 'HH24:MI:SS') , I get: 如果我使用TO_CHAR(TX_TIME, 'HH24:MI:SS') ,我得到:

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

Where does 2009-08-01 come from? 2009-08-01来自哪里?

Oracle does not have a Java type for time. Oracle没有Java类型的时间。 The java.sql.Time class is mapped to the oracle.sql.DATE class, even in the latest drivers. 即使在最新的驱动程序中,java.sql.Time类也映射到oracle.sql.DATE类。 Documentation Here What you should do is have the "day" portion of TX_TIME be some standard value (say 1970-01-01). 这里的文档您应该做的是让TX_TIME的“ day”部分成为一些标准值(例如1970-01-01)。 Then you can query on this column with a static "day" and have the time work as expected. 然后,您可以在该列中使用静态的“天”进行查询,并使时间按预期方式工作。

Depending upon what version of the Oracle drivers you're using, the handling of java.sql.Date and java.sql.Timestamp for an Oracle DATE column type is different. 根据您使用的Oracle驱动程序版本,Oracle DATE列类型对java.sql.Date和java.sql.Timestamp的处理有所不同。 Check the JDBC FAQ for more info. 查看JDBC常见问题以获取更多信息。 Good luck! 祝好运!

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")
         );
      }

I assume that you are using a PreparedStatement in this? 我假设您正在使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM