Fork me on GitHub

Pgsql Json/Jsonb格式数据更新key值覆盖问题

  先贴出问题,pgsql中某jsonb 字段,原始值为{"a":{"a":"b","c":"d"}},来了一个新值{"a":{"a":"e","f":"g"}},我想要的最终值为{"a":{"a":"e","c":"d","f":"g"}},可是使用||操作,结果却是{"a": {"a": "e", "f": "g"}},将之前的值完全覆盖了,其实我想仍旧保留{"c":"d"}.

同时我也试了下单层结构json数据更新操作,完全没问题

 另外我也使用了jsonb_set函数处理多层json数据,仍旧不能满足我的要求

解释:jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])四个参数的含义

  target:原json数据  path:新json数据期望在原json数据中的路径,不存在则新增,存在则修改,如{a,a} 第一个a表示原数据第一层key-a,第二个a表示原数据第二次key-a

  new_value 期望插入/更新的json数据  create_missing:值为 true:如果元素值不存在,则添加;false:元素值不存在,不添加 (默认为true)

 

另外我也试了jsonb_set仅针对某一key进行单独的更新操作是可以成功的

进过上面的四轮测试,大致可以得出结论:pgsql官方提供的||操作和jsonb_set函数仅支持单层json格式数据的更新,无法实现我需求里面的多层json数据更新。

那么怎么实现最初的需求呢?思来想去,居然官方提供的方法或者函数只能实现单层json更新,也只能自定义函数来实现了--思路很简单,对原数据和新数据进行递归,一层层的更新。

下面贴出写的函数,基本能够满足上面的需求。各位大佬有更优方案也可以一起探讨。

关于pgsql function语法参考官方:pgsql create function

CREATE OR REPLACE FUNCTION jsonb_update(val1 JSONB,val2 JSONB)
        RETURNS JSONB AS $$
    DECLARE
    result JSONB;
        v RECORD;
    BEGIN
        IF jsonb_typeof(val1) != 'null' THEN
            IF jsonb_typeof(val2) != 'null' THEN
                result = val1;
                FOR v IN SELECT key,value FROM jsonb_each(val2)
                LOOP
                    IF jsonb_typeof(val1->v.key) != 'null' AND jsonb_typeof(val2->v.key) = 'object'
                            AND jsonb_typeof(val1->v.key) = 'object' THEN
                        result = result || jsonb_build_object(v.key, jsonb_update(val1->v.key, val2->v.key));
                    ELSE
                        result = result || jsonb_build_object(v.key, v.value);
                    END IF;
                END LOOP;
                RETURN result;
            ELSE
               RETURN val1;
            END IF;
        ELSE
            IF jsonb_typeof(val2) != 'null' THEN
               RETURN val2;
            ELSE
               RETURN result;
            END IF;
        END IF;
    END;
    $$ LANGUAGE plpgsql;

看下效果:

单层json格式数据更新:新的json格式是想要的效果

 多层json格式数据更新:满足需求

 

posted @ 2022-08-24 16:01  JackpotHan  阅读(1218)  评论(0编辑  收藏  举报