我尝试使用 H2 数据库 (v1.4.185) 比较 jOOQ (v3.5.0) 中的日期,但如果比较太大,我会得到“数值超出范围”。
例如,如下表
CREATE TABLE example (
id INT AUTO_INCREMENT,
deadline TIMESTAMP,
PRIMARY KEY (id)
);
并使用以下示例代码(未显示 jOOQ 的代码生成步骤)
DSLContext dsl = DSL.using(getDataSource(dbUrl), SQLDialect.H2);
ExampleRecord exampleRecord = dsl.newRecord(EXAMPLE);
exampleRecord.setDeadline(Timestamp.valueOf("2001-01-10 12:15:30"));
exampleRecord.store();
dsl.selectFrom(EXAMPLE)
.where(EXAMPLE.DEADLINE.sub(
DayToSecond.valueOf(Duration.ofDays(30).toMillis()))
.le(currentTimestamp()))
.fetch().forEach(record -> System.out.println(record.getDeadline()));
产生以下错误
Exception in thread "main" org.jooq.exception.DataAccessException:
SQL [select "EXAMPLE"."ID", "EXAMPLE"."DEADLINE" from "EXAMPLE"
where dateadd('ms', cast(? as bigint), "EXAMPLE"."DEADLINE")
<= current_timestamp()];
Numeric value out of range: "-2592000000";
SQL statement:
select "EXAMPLE"."ID", "EXAMPLE"."DEADLINE" from "EXAMPLE"
where dateadd('ms', cast(? as bigint), "EXAMPLE"."DEADLINE")
<= current_timestamp() [22003-185]
最佳答案
对我来说,这似乎是 H2 的一个缺陷。 H2的DATEADD()
function expects the number of units added to be of type int
。当然,当以毫秒为单位进行操作时,这是没有意义的。 I've reported it on the H2 user group 。让我们看看他们怎么说。如果这个问题在 H2 中无法纠正,我们将在 jOOQ 中解决这个问题,就像我们对 Sybase 和其他数据库所做的那样。
解决方法:
Field.sub(Number)
方法在用于日期时间算术时已经从时间戳中减去天数(如 Oracle)。因此,您可以编写相同的表达式:
EXAMPLE.DEADLINE.sub(30)
另一个选择是使用 DSL.timestampAdd()
相反:
timestampAdd(EXAMPLE.DEADLINE, -30, DatePart.DAY);
第三种选择是使用纯 SQL:
public static Field<Timestamp> mySub(Field<Timestamp> field, Number days) {
return DSL.field("dateadd('day', {0}, {1})", Timestamp.class, val(-days), field);
}
关于java - jOOQ 中减去日期的数值超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29072651/