java DslContext Jooq更新时间戳,时区列为空

sc4hvdpw  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(204)

我在postgres DB中有一个Customer表,id作为主键,下面是列

id -> Integer(PK)
name -> Varchar2
details-> jsonb
created_timestamp -> TIMESTAMP WITH TIME ZONE

我正在尝试使用dslContext基于主键更新表。resultQuery方法,我必须更新jsonb列的namedetails并将created_timestamp设置为null

String sql = "UPDATE customer SET name = :name, details = :details, created_timestamp = 'NULL' where id = :id RETURNING id";

Java代码

List<Map<String,Object>> updatedCapacityResult = dslContext.resultQuery(sql,
      DSL.param("name","value"),
      DSL.param("details",objectmapper.writeValueAsString(object))).fetchMaps();

我有错误,而执行的代码,它只是说

org.jooq.exception.DataAccessException: SQL [UPDATE customer SET name = :name, details = :details, created_timestamp = 'NULL' where id = :id RETURNING id; ERROR: syntax error at or near "details"
 Position: 60

当我删除更新details的代码时,它开始在created_timestamp字段上出错,如果我只是使用上面的查询更新name,它也会更新并返回数据。
好奇我在这里错过了什么,以及如何更新jsonbtimestamp列?

x8diyxa7

x8diyxa71#

JSONB列

虽然有时pgjdbc驱动程序和PostgreSQL服务器可以将字符串值强制转换为JSONB值,但它并不总是有效,因此最安全的方法是始终显式转换。即:

details = cast(:details as jsonb)

NULL

您没有将时间戳设置为NULL(值),而是将其设置为'NULL'(字符串文字)。省略撇号就行了

created_timestamp = NULL

使用代码生成器和DSL

您可能有这样使用普通SQL的理由,但请注意,jOOQ的API、DSL和代码生成器会透明地为您处理所有这些事情。你只要写:

ctx.update(CUSTOMER)
   .set(CUSTOMER.NAME, name)

   // You could even attach a Converter to this column to auto-convert
   // between your object representation and the JSONB representation!
   .set(CUSTOMER.DETAILS, jsonb(objectmapper.writeValueAsString(object)))
   .setNull(CUSTOMER.CREATED_TIMESTAMP)
   .returning()
   .fetchMaps();

请参阅why it is usually recommended to use code generation with jOOQ上的这篇博客文章。

相关问题