1

我正在使用 jooq 为 Oracle 构建查询。除日期外,一切正常:

public static void main(String[] args) throws SQLException {
    java.sql.Timestamp now = new java.sql.Timestamp(new Date().getTime());
    Connection con = DriverManager.getConnection(... , ... , ...);
    final Factory create = new OracleFactory(con);
    Statement s = con.createStatement();
    s.execute("create table test_table ( test_column DATE )");
    s.execute("insert into test_table values (to_date('20111111', 'yyyymmdd'))");

    // -- using to_date
    ResultSet rs = s.executeQuery("select count(1) from test_table where test_column<to_date('20121212', 'yyyymmdd')");
    rs.next();
    System.out.println(""+rs.getInt(1));
    rs.close();     

    // -- using a preparedstatement with java.sql.timestamp
    PreparedStatement ps = con.prepareStatement("select count(1) from test_table where test_column<?");
    ps.setTimestamp(1,now);
    rs = ps.executeQuery();
    rs.next();
    System.out.println(""+rs.getInt(1));
    rs.close();

    // -- using jooq with java.sql.timestamp
    final org.jooq.Table<org.jooq.Record> table = create.tableByName("TEST_TABLE");
    final org.jooq.SelectSelectStep sss = create.select(create.count());
    final org.jooq.SelectJoinStep sjs = sss.from(table);
    final org.jooq.SelectConditionStep scs = sjs.where(create.fieldByName("TEST_COLUMN").lessThan(now));
    System.out.println(scs.toString());
    rs = s.executeQuery(scs.toString());
    rs.next();
    System.out.println(""+rs.getInt(1));
    rs.close();

    s.close();

}

给出以下输出:

   1
   1
   select count(*) from "TEST_TABLE" where "TEST_COLUMN" < '2012-12-12 19:42:34.957'
   Exception in thread "main" java.sql.SQLDataException: ORA-01861: literal does not match format string

我原以为 JOOQ 会检查 lessThan(Object) 中的 Object 类型以确定它是否可以提出合理的转换,但显然在这种情况下它只是执行 Object.toString() 。我还记得我从来没有在 MySQL 中通过 JOOQ 进行日期查询的问题(尽管这是前一阵子)。我究竟做错了什么?

4

1 回答 1

1

我怀疑这个问题是由于create.fieldByName()不知道列的类型(因此是对象),并在比较谓词的右侧强制该未知类型。这应该在 jOOQ 中修复。我为此注册了#2007: https ://github.com/jOOQ/jOOQ/issues/2007

同时,尝试在您的字段上明确设置类型:

create.fieldByName(Timestamp.class, "TEST_COLUMN").lessThan(now)
于 2012-12-13T07:59:23.517 回答