我正试图在Kotlin中使用jooq运行以下形式的查询:
val create = DSL.using(SQLDialect.POSTGRES)
val query: Query = create.select().from(DSL.table(tableName))
.where(DSL.field("timestamp").between("1970-01-01T00:00:00Z").and("2021-11-05T00:00:00Z"))
.orderBy(DSL.field("id").desc())
上面的代码给了我:
syntax error at or near "and
此外,在调试器中查看此查询,query.sql
呈现为:
select * from data_table where timestamp between ? and ? order by id desc
我不确定?
是否指示它无法将值呈现给SQL,或者它们是某种占位符。。
此外,该代码在没有where
链的情况下工作。
此外,在Postgres命令行上,我可以运行以下命令并执行查询:
select * from data_table where timestamp between '1970-01-01T00:00:00Z' and '2021-11-05T00:00:00Z' order by id
查询架构上的数据类型,timestamp
列类型呈现为timestamp without time zone
。
在我将变量声明为:之前
val lowFilter = "1970-01-01T00:00:00Z"
val highFilter = "2021-11-05T00:00:00Z"
这不起作用,似乎传递原始字符串也不起作用。我对这个很陌生,所以我很确定我把这里的用法搞砸了。
EDIT按照@nulldroid的建议,做了一些类似的事情:
.where(DSL.field("starttime").between(DSL.timestamp("1970-01-01T00:00:00Z")).and(DSL.timestamp("2021-11-05T00:00:00Z")))
这导致:
Type class org.jooq.impl.Val is not supported in dialect POSTGRES"
不使用代码生成器:
我假设您有充分的理由不为这个特定的查询使用代码生成器,主要原因通常是您的模式是动态的。
因此,编写查询的正确方法是:
create.select()
.from(DSL.table(tableName))
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(DSL.field("timestamp", SQLDataType.OFFSETDATETIME)
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(DSL.field("id").desc())
请注意,我是如何使用实际的时态数据类型,而不是字符串来比较日期和声明字段的。
根据您问题的UTC时间戳,我假设您使用的是TIMESTAMPTZ
。否则,如果您使用TIMESTAMP
,只需将OffsetDateTime
替换为LocalDateTime
。。。
使用代码生成器
如果使用代码生成器,如果你的模式不是动态的,总是建议使用,你会写与上面几乎相同的东西,但键入安全的:
create.select()
.from(MY_TABLE)
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(MY_TABLE.TIMESTAMP
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(MY_TABLE.ID.desc())