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

问题描述 投票:0回答:2

我在 postgres 数据库中有

Customer
表,其中
id
作为主键和以下列

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

我正在尝试使用 dslContext.resultQuery 方法基于主键更新表,我必须更新

name
details
jsonb 列并将
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
它也会更新并返回数据。

好奇我在这里错过了什么以及如何更新

jsonb
timestamp
专栏?

java jooq ratpack
2个回答
1
投票

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();

请参阅这篇关于为什么通常建议使用 jOOQ 进行代码生成 的博客文章。


0
投票

我无法弄清楚

jooq
库的问题,但是在将值更新为
NULL
时,我找到了替代方法,例如使用
StringBuilder
并将其形成为字符串

String sql = new StringBuilder("UPDATE customer SET" )
                .append("name = '"+name+"', ")
                .append("details = '"+details+"', ")
                .append("created_timestamp = NULL ")
                .append("where id = '"+id+"' RETURNING id").toString();

和刚刚使用

resultQuery

 List<Map<String,Object>> updatedCapacityResult = dslContext.resultQuery(sql).fetchMaps();
© www.soinside.com 2019 - 2024. All rights reserved.