带有jooq的postgres数组范围表示法

Posted

技术标签:

【中文标题】带有jooq的postgres数组范围表示法【英文标题】:postgres array range notation with jooq 【发布时间】:2021-12-07 03:51:54 【问题描述】:

在我的 postgres 数据库中,我有一个 json 数组 (json[]) 以跟踪 json 对象形式的错误。如果有更新,我想将最新的错误附加到该数组,但只保留最新的 5 个错误(所有 sql 都已简化):

update dc
set 
    error_history           =
        array_append(dc.error_history[array_length(dc.error_history, 1) - 4:array_length(dc.error_history, 1)+1], cast('"blah": 6' as json))
where dc.id = 'f57520db-5b03-4586-8e77-284ed2dca6b1'
;

这在本机 sql 中运行良好,我尝试在 jooq 中复制它,如下所示:

.set(dc.ERROR_HISTORY,
    field("array_append(dc.error_history[array_length(dc.error_history, 1) - 4:array_length(dc.error_history, 1) + 1], cast('0' as json))", dc.ERROR_HISTORY.getType(), latestError)
);

但似乎: 导致库认为那里有一个绑定参数。生成的sql是:

array_append(dc.error_history[array_length(dc.error_history, 1) - 4?(dc.error_history, 1) + 1], cast('0' as json)

我得到的错误是

nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "$5"

我完全同意:D

有没有办法在 java 代码中转义 : 或者有更好的方法来做到这一点?

编辑: 我还尝试使用arrayRemove 函数在更新时删除第一个元素,但这也不起作用,因为它不能按索引工作,而是按元素工作,并且 postgres 不知道如何检查 json 元素是否相等。

【问题讨论】:

【参考方案1】:

天哪,答案真的很简单:D

field("array_append(dc.error_history[array_length(dc.error_history, 1) - 4 : array_length(dc.error_history, 1) + 1], cast(0 as json))", dc.ERROR_HISTORY.getType(), latestError)

只需在冒号周围添加空格即可正常工作。请注意,我在0 周围加上单引号犯了另一个错误,因为latestError 对象已经是JSON 类型。

【讨论】:

这是有效的,因为它打破了 jOOQ 的假设,即 :xyz 是命名参数文字,它们在许多方言中都有(但不是 PG,语法为 $xyz 是的,我马上就意识到了,谢谢你的回答:)

以上是关于带有jooq的postgres数组范围表示法的主要内容,如果未能解决你的问题,请参考以下文章

Jooq postgre 在 play2.5 scala 中插入错误

JOOQ 代码生成器跳过包含 JsonNode 字段的类

具有多个数组的 unnest 的 Jooq 表示法

Jooq 无法找到 postgres 数据库的驱动程序

Jooq Postgres JSON 查询

如何使用 JOOQ 使用 H2 为 PostGres 生成存根 - ENUM 类型