我在 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
专栏?
虽然有时 pgjdbc 驱动程序和 PostgreSQL 服务器可以将字符串值强制转换为
JSONB
值,但它并不总是有效,所以最安全的选择是始终显式转换,即:
details = cast(:details as jsonb)
NULL
价值您没有将时间戳设置为
NULL
(值),而是将其设置为'NULL'
(字符串文字)。只需省略撇号
created_timestamp = NULL
你可能有这样使用纯 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 进行代码生成 的博客文章。
我无法弄清楚
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();