JOOQ操作PostgreSQL json[]数组追加保留最新5条的冒号转义问题
解决方案
方案1:转义冒号
JOOQ的Plain SQL模板中,冒号默认会被识别为命名参数的前缀,要输出字面量冒号,只需要在冒号前加转义符\,Java字符串中需要写成\\即可。另外注意不要给占位符{0}加单引号,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 ) );
方案2:使用JOOQ原生函数(更推荐)
完全避免手写Plain SQL,用JOOQ内置的数组操作函数实现逻辑,可读性和可维护性更高,也不会出现符号识别问题:
// 计算数组当前长度 Field<Integer> arrLen = DSL.arrayLength(dc.ERROR_HISTORY, 1); // 切片取最多最近4条记录(长度不足时自动取全部) Field<JSON[]> slicedHistory = DSL.arraySlice(dc.ERROR_HISTORY, arrLen.sub(4), arrLen.add(1)); // 追加最新错误 Field<JSON[]> newHistory = DSL.arrayAppend(slicedHistory, DSL.cast(DSL.val(latestError), JSON.class)); // 写入字段 .set(dc.ERROR_HISTORY, newHistory)
这个实现和你原生SQL的逻辑完全一致,不需要额外处理数组长度小于5的边界情况,PostgreSQL的数组切片逻辑在起始位置小于1时会自动从数组第一个元素开始截取。
内容的提问来源于stack exchange,提问作者Armin Walland
相关产品推荐
相关产品推荐

