[英]Numeric value out of range subtracting dates in jOOQ
我正在尝试使用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()
函数期望添加的单位数为int
类型 。 当然,以毫秒为单位进行操作是没有意义的。 我已经在H2用户组中进行了举报 。 让我们看看他们怎么说。 如果在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);
}
该错误对我来说没有意义。 生成的SQL( bigint
)表明jOOQ知道该参数很long
并且-2592000000
完全在限制内。
我想知道错误消息是否添加了引号,或者DayToSecond.toMillis()
是否返回String
而不是long
。 除非我期望会有不同的错误消息(加上编译错误)。
为了安全起见,尝试通过用常量替换代码来降低表达式的复杂性:
dsl.selectFrom(EXAMPLE)
.where(EXAMPLE.DEADLINE.sub(-2592000000L))
...
只是看看它如何影响错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.