替换 json 数据中的多个值非常复杂,因为您需要分解 json 数据结构,然后手动重建它。另外,当你想替换同一个json数据中的多个值时,你需要先创建自己的基于jsonb_set的聚合函数。
将您的 jsonb 数据视为一个字符串可能要简单得多:
CREATE OR REPLACE FUNCTION code_md5 (x jsonb) RETURNS jsonb LANGUAGE sql AS $$
SELECT string_agg(CASE WHEN a.ordinality = 1 THEN a ELSE c.md5_val || substr(a, length(b.val)+1) END, '"code": "') :: jsonb
FROM regexp_split_to_table(x :: text, '"code": "') with ordinality AS a
CROSS JOIN LATERAL (SELECT (regexp_match(a, '[^"]+'))[1] AS val) AS b
CROSS JOIN LATERAL (SELECT md5(b.val) AS md5_val) as c ;
$$ ;
此函数的第一步使用“代码”:“作为分隔符拆分 json 数据。
第二步查找与键“代码”关联的值。
第三步计算哈希值。
最后一步将不同的部分连接在一起,同时用相应的哈希值替换 json 值。
结果是:
{
"code": "900150983cd24fb0d6963f7d28e17f72",
"param": 1,
"nested": [
{
"code": "4911e516e5aa21d327512e0c8b197616",
"param": 11,
"nested": {}
},
{
"code": "7888d65a43501d992cc38638b59964d6",
"param": 22,
"nested": {}
}
]
}
在与键“code”关联的json值内部使用双引号的情况不在该函数的范围内(结果将是错误的)。
见dbfiddle