如何修改新的PostgreSQL JSON数据类型中的字段?

如何修改新的PostgreSQL JSON数据类型中的字段?,第1张

概述使用postgresql 9.3我可以选择JSON数据类型的特定字段,但是如何使用UPDATE修改它们?我找不到任何这样的例子在postgresql文档,或在任何地方在线。我试过明显: postgres=# create table test (data json);CREATE TABLEpostgres=# insert into test (data) values ('{"a":1," 使用postgresql 9.3我可以选择JsON数据类型的特定字段,但是如何使用UPDATE修改它们?我找不到任何这样的例子在postgresql文档,或在任何地方在线。我试过明显:
postgres=# create table test (data Json);CREATE tablepostgres=# insert into test (data) values ('{"a":1,"b":2}');INSERT 0 1postgres=# select data->'a' from test where data->>'b' = '2'; ?column?---------- 1(1 row)postgres=# update test set data->'a' = to_Json(5) where data->>'b' = '2';ERROR:  Syntax error at or near "->"liNE 1: update test set data->'a' = to_Json(5) where data->>'b' = '2...
更新: With PostgreSQL 9.5,在Postgresql本身中有一些Jsonb *** 作的功能(但是没有一个用于Json; cast需要 *** 作Json值)。

合并2个(或多个)JsON对象(或连接数组):

SELECT Jsonb '{"a":1}' || Jsonb '{"b":2}',-- will yIEld Jsonb '{"a":1,"b":2}'       Jsonb '["a",1]' || Jsonb '["b",2]'  -- will yIEld Jsonb '["a",1,"b",2]'

因此,设置一个简单的密钥可以使用:

SELECT Jsonb '{"a":1}' || Jsonb_build_object('<key>','<value>')

其中< key>应为字符串,< value>可以是to_Jsonb()接受的任何类型。

对于在JsON层次结构中深度设置值,可以使用Jsonb_set()函数:

SELECT Jsonb_set('{"a":[null,{"b":[]}]}','{a,b,0}',Jsonb '{"c":3}')-- will yIEld Jsonb '{"a":[null,{"b":[{"c":3}]}]}'

Jsonb_set()的完整参数列表:

Jsonb_set(target Jsonb,path text[],new_value Jsonb,create_missing boolean default true)

从JsON对象(或从数组)中删除键(或索引)可以使用 – 运算符完成:

SELECT Jsonb '{"a":1,"b":2}' - 'a',-- will yIEld Jsonb '{"b":2}'       Jsonb '["a",2]' - 1    -- will yIEld Jsonb '["a",2]'

在JsON层次结构中从深层删除,可以使用# – 运算符:

SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,0}'-- will yIEld Jsonb '{"a":[null,{"b":[]}]}'

原始答案:这是可能的(没有plpython或plv8)在纯sql也(但需要9.3,将不能与9.2工作)

CREATE OR REPLACE FUNCTION "Json_object_set_key"(  "Json"          Json,"key_to_set"    TEXT,"value_to_set"  anyelement)  RETURNS Json  LANGUAGE sql  IMMUtable  STRICTAS $function$SELECT concat('{',string_agg(to_Json("key") || ':' || "value",','),'}')::Json  FROM (SELECT *          FROM Json_each("Json")         WHERE "key" <> "key_to_set"         UNION ALL        SELECT "key_to_set",to_Json("value_to_set")) AS "fIElds"$function$;

SQLFiddle

编辑:

一个版本,它设置多个键&值:

CREATE OR REPLACE FUNCTION "Json_object_set_keys"(  "Json"          Json,"keys_to_set"   TEXT[],"values_to_set" anyarray)  RETURNS Json  LANGUAGE sql  IMMUtable  STRICTAS $function$SELECT concat('{','}')::Json  FROM (SELECT *          FROM Json_each("Json")         WHERE "key" <> ALL ("keys_to_set")         UNION ALL        SELECT disTINCT ON ("keys_to_set"["index"])               "keys_to_set"["index"],CASE                 WHEN "values_to_set"["index"] IS NulL THEN 'null'::Json                 ELSE to_Json("values_to_set"["index"])               END          FROM generate_subscripts("keys_to_set",1) AS "keys"("index")          JOIN generate_subscripts("values_to_set",1) AS "values"("index")         USING ("index")) AS "fIElds"$function$;

编辑2:作为@ErwinBrandstetter noted上面的这些功能像一个所谓的UPSERT(更新一个字段,如果存在,插入如果它不存在)。这里是一个变体,其中只有UPDATE:

CREATE OR REPLACE FUNCTION "Json_object_update_key"(  "Json"          Json,"value_to_set"  anyelement)  RETURNS Json  LANGUAGE sql  IMMUtable  STRICTAS $function$SELECT CASE  WHEN ("Json" -> "key_to_set") IS NulL THEN "Json"  ELSE (SELECT concat('{','}')          FROM (SELECT *                  FROM Json_each("Json")                 WHERE "key" <> "key_to_set"                 UNION ALL                SELECT "key_to_set",to_Json("value_to_set")) AS "fIElds")::JsonEND$function$;

编辑3:这是递归变量,它可以设置(UPSERT)叶值(并使用来自此答案的第一个函数),位于键路径(其中键只能引用内部对象,不支持内部数组):

CREATE OR REPLACE FUNCTION "Json_object_set_path"(  "Json"          Json,"key_path"      TEXT[],"value_to_set"  anyelement)  RETURNS Json  LANGUAGE sql  IMMUtable  STRICTAS $function$SELECT CASE COALESCE(array_length("key_path",1),0)         WHEN 0 THEN to_Json("value_to_set")         WHEN 1 THEN "Json_object_set_key"("Json","key_path"[l],"value_to_set")         ELSE "Json_object_set_key"(           "Json","Json_object_set_path"(             COALESCE(NulliF(("Json" -> "key_path"[l])::text,'null'),'{}')::Json,"key_path"[l+1:u],"value_to_set"           )         )       END  FROM array_lower("key_path",1) l,array_upper("key_path",1) u$function$;

更新:功能现在紧凑。

总结

以上是内存溢出为你收集整理的如何修改新的PostgreSQL JSON数据类型中的字段?全部内容,希望文章能够帮你解决如何修改新的PostgreSQL JSON数据类型中的字段?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1172941.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存