अद्यतन : PostgreSQL 9.5 के साथ, PostgreSQL केjsonb
भीतर कुछ हेरफेर कार्यक्षमता हैं (लेकिन मूल्यों के साथ json
छेड़छाड़ करने के लिए कलाकारों की आवश्यकता नहीं है 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,1,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)
path
JSON सरणी अनुक्रमणिका को भी शामिल कर सकते हैं और नकारात्मक पूर्णांक जो JSON सरणियों के अंत से गिनती में दिखाई देते हैं। हालाँकि, गैर-मौजूदा, लेकिन पॉजिटिव JSON एरे इंडेक्स तत्व को एरे के अंत में जोड़ देगा:
SELECT jsonb_set('{"a":[null,{"b":[1,2]}]}', '{a,1,b,1000}', jsonb '3', true)
-- will yield jsonb '{"a":[null,{"b":[1,2,3]}]}'
JSON सरणी में डालने के लिए (सभी मूल मूल्यों को संरक्षित करते हुए) , jsonb_insert()
फ़ंक्शन का उपयोग किया जा सकता है ( 9.6+ में; यह फ़ंक्शन केवल, इस खंड में ):
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b,0}', jsonb '2')
-- will yield jsonb '{"a":[null,{"b":[2,1]}]}', and
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b,0}', jsonb '2', true)
-- will yield jsonb '{"a":[null,{"b":[1,2]}]}'
पूर्ण पैरामीटर सूची jsonb_insert()
:
jsonb_insert(target jsonb,
path text[],
new_value jsonb,
insert_after boolean default false)
फिर से, नकारात्मक पूर्णांक जो path
JSON सरणियों के अंत से गिनती में दिखाई देते हैं।
तो, एफ.एक्स। एक JSON सरणी के अंत में आवेदन किया जा सकता है:
SELECT jsonb_insert('{"a":[null,{"b":[1,2]}]}', '{a,1,b,-1}', jsonb '3', true)
-- will yield jsonb '{"a":[null,{"b":[1,2,3]}]}', and
हालांकि, इस समारोह थोड़ा अलग ढंग से (से काम कर रहा है jsonb_set()
) जब path
में target
एक JSON ऑब्जेक्ट के लिए महत्वपूर्ण है। उस स्थिति में, यह केवल JSON ऑब्जेक्ट के लिए एक नया कुंजी-मूल्य जोड़ी जोड़ देगा जब कुंजी का उपयोग नहीं किया जाता है। यदि इसका उपयोग किया जाता है, तो यह एक त्रुटि उत्पन्न करेगा:
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,c}', jsonb '[2]')
-- will yield jsonb '{"a":[null,{"b":[1],"c":[2]}]}', but
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b}', jsonb '[2]')
-- will raise SQLSTATE 22023 (invalid_parameter_value): cannot replace existing key
JSON ऑब्जेक्ट से एक कुंजी (या एक इंडेक्स) हटाना (या, एक सरणी से) -
ऑपरेटर के साथ किया जा सकता है :
SELECT jsonb '{"a":1,"b":2}' - 'a', -- will yield jsonb '{"b":2}'
jsonb '["a",1,"b",2]' - 1 -- will yield jsonb '["a","b",2]'
JSON पदानुक्रम में गहरे से हटाकर,#-
ऑपरेटर के साथ किया जा सकता है :
SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,1,b,0}'
-- will yield jsonb '{"a":[null,{"b":[]}]}'
9.4 के लिए , आप मूल उत्तर (नीचे) के संशोधित संस्करण का उपयोग कर सकते हैं, लेकिन JSON स्ट्रिंग को एग्रीगेट करने के बजाय, आप सीधे किसी json ऑब्जेक्ट में एग्रीगेट कर सकते हैं json_object_agg()
।
मूल उत्तर : शुद्ध एसक्यूएल में भी यह (प्लिफ़थॉन या plv8 के बिना) संभव है (लेकिन 9.3+ की ज़रूरत है, पहले नहीं होगा)
CREATE OR REPLACE FUNCTION "json_object_set_key"(
"json" json,
"key_to_set" TEXT,
"value_to_set" anyelement
)
RETURNS json
LANGUAGE sql
IMMUTABLE
STRICT
AS $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
STRICT
AS $function$
SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::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 ने उपरोक्त कार्यों को एक तथाकथित की तरह काम किया है UPSERT
(यदि यह मौजूद है तो फ़ील्ड को अपडेट करता है, अगर यह मौजूद नहीं है तो सम्मिलित करता है)। यहाँ एक संस्करण है, जो केवल UPDATE
:
CREATE OR REPLACE FUNCTION "json_object_update_key"(
"json" json,
"key_to_set" TEXT,
"value_to_set" anyelement
)
RETURNS json
LANGUAGE sql
IMMUTABLE
STRICT
AS $function$
SELECT CASE
WHEN ("json" -> "key_to_set") IS NULL THEN "json"
ELSE (SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')
FROM (SELECT *
FROM json_each("json")
WHERE "key" <> "key_to_set"
UNION ALL
SELECT "key_to_set", to_json("value_to_set")) AS "fields")::json
END
$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
STRICT
AS $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",
"key_path"[l],
"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$;
अद्यतन : फ़ंक्शंस को अब कॉम्पैक्ट किया जाता है।
select json_object_set_key((select data from test where data->>'b' = '2'), 'b', 'two');
त्रुटि संदेशERROR: could not determine polymorphic type because input has type "unknown"