Kotlin/Java中使用jOOQ DSL编写where子句报错如何解决
问题根因
- 你看到的SQL里的
?是jOOQ默认生成的预编译占位符,属于正常逻辑,不是渲染失败。 - 首次报错
syntax error at or near "and"是因为你没有显式指定timestamp字段的类型,jOOQ默认将其识别为字符串类型,和数据库实际的timestamp without time zone类型不匹配,导致SQL语法异常。 - 后续修改后报
Type class org.jooq.impl.Val is not supported in dialect POSTGRES,是因为DSL.timestamp()方法在你使用的jOOQ版本中与Postgres方言存在兼容性问题,替换为更规范的类型绑定写法即可解决。
解决方案
方案1(推荐):使用JDK时间类型绑定
直接将时间字符串转换为LocalDateTime(对应Postgres的timestamp without time zone类型),同时显式指定字段的SQL类型:
import java.time.LocalDateTime import java.time.format.DateTimeFormatter import org.jooq.impl.SQLDataType // 先把字符串转为对应时间类型 val lowFilter = LocalDateTime.parse("1970-01-01T00:00:00Z", DateTimeFormatter.ISO_DATE_TIME) val highFilter = LocalDateTime.parse("2021-11-05T00:00:00Z", DateTimeFormatter.ISO_DATE_TIME) val create = DSL.using(SQLDialect.POSTGRES) val query: Query = create.select().from(DSL.table(tableName)) // 显式指定字段类型为TIMESTAMP .where(DSL.field("timestamp", SQLDataType.TIMESTAMP).between(lowFilter).and(highFilter)) .orderBy(DSL.field("id").desc())
方案2:直接内联字符串字面量
如果你不需要预编译占位符,希望生成的SQL和你在命令行执行的完全一致,可以用DSL.inline()方法将时间字符串直接嵌入SQL:
import org.jooq.impl.SQLDataType val query: Query = create.select().from(DSL.table(tableName)) .where(DSL.field("timestamp", SQLDataType.TIMESTAMP) .between(DSL.inline("1970-01-01T00:00:00Z")) .and(DSL.inline("2021-11-05T00:00:00Z")) ) .orderBy(DSL.field("id").desc())
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

