आपने पहले ही पाया है कि आप अभिव्यक्ति का परीक्षण कर सकते हैं user_info->>'username'
न्यूल के लिए। लेकिन आपका कार्य अभी भी बहुत अक्षम है . और अभी भी अस्पष्टताएं हैं ।
पोस्टग्रेज 9.3 में बेहतर समाधान
एकाधिक स्तंभों के लिए एक पंक्ति को बार-बार अद्यतन करना महंगा है। Postgres प्रत्येक अद्यतन के लिए एक नया पंक्ति संस्करण लिखता है। एक एकल . का उपयोग करें अपडेट करें
यदि संभव हो तो:
CREATE OR REPLACE FUNCTION sp_update_user(_user_id int, _user_info json)
RETURNS json AS
$func$
BEGIN
UPDATE users u
SET firstname = COALESCE(_user_info->>'firstname', u.firstname)
, lastname = COALESCE(_user_info->>'lastname' , u.lastname)
WHERE id = sp_update_user._user_id
AND ((_user_info->>'firstname') IS NOT NULL OR
(_user_info->>'lastname') IS NOT NULL);
IF FOUND THEN
RETURN '{"success":true}'::json;
ELSE
RETURN '{"success":false}'::json;
END IF;
END
$func$ LANGUAGE plpgsql;
कॉल करें:
SELECT sp_update_user(123, '{"firstname": "jon", "lastname": "doe"}')
-
यह अनेक स्तंभों के लिए काफी तेज़ है, क्योंकि केवल एक
अद्यतन
(अधिकतम) निष्पादित किया जाता है। अगरकहां
खंडसत्य
का मूल्यांकन नहीं करता है , कोई अपडेट बिल्कुल नहीं होता है और आपको'{"success":false}'
मिलता है परिणाम के रूप में। -
यदि कभी-कभी तालिका में मान पहले से ही बदले जा रहे हैं, तो एक और अनुकूलन संभव है। इस संबंधित उत्तर के अंतिम पैराग्राफ पर विचार करें:
-
चर / पैरामीटर
user_id
आपके मूल में गायब है। -
अभी भी एक कोने का मामला है अस्पष्टता . यदि तत्व मौजूद है और JSON
null
पर सेट है , आपको एक SQLNULL
भी मिलता है परिणाम के रूप में। विचार करें:SELECT ('{"b": null}'::json->>'b') IS NULL AS b_is_null , ('{"c": 2}'::json->>'b') IS NULL AS b_missing;
-
सुनिश्चित नहीं हैं कि आप डेटा प्रकार का उपयोग क्यों करते हैं
json
वापसी प्रकार के रूप में, मैंने इसे अभी रखा है। लेकिन अगर फ़ंक्शन अपडेट नहीं होता है, तो आप सुनिश्चित नहीं हो सकते कि आपकोगलत
क्यों मिलता है . दिए गएid
. के साथ कोई पंक्ति नहीं हो सकती है , प्रमुख नाम'firstname'
और'अंतिम नाम'
गायब हो सकता है - याशून्य
हो सकता है ...
पोस्टग्रेज 9.4 में बेहतर समाधान
एक साफ है और Postgres में सरल समाधान 9.4 jsonb
. के साथ ?
"अस्तित्व" ऑपरेटर
- जो बड़ी तालिकाओं के लिए एक अनुक्रमणिका का उपयोग भी कर सकता है (आपके फ़ंक्शन में प्रासंगिक नहीं):
SELECT ('{"b": null}'::jsonb ? 'b') AS b_is_null
, ('{"c": 2}'::jsonb ? 'b') AS b_missing;
और ?|
और ?&
वेरिएंट
एक साथ कई कुंजियों की जांच करने के लिए।
ताकि हम इसे लागू कर सकें:
CREATE OR REPLACE FUNCTION sp_update_user(_user_id int, _user_info jsonb)
RETURNS jsonb AS
$func$
BEGIN
UPDATE users u
SET firstname = CASE WHEN _user_info ? 'firstname' THEN _user_info->>'firstname' ELSE u.firstname END
, lastname = CASE WHEN _user_info ? 'lastname' THEN _user_info->>'lastname' ELSE u.lastname END
WHERE id = sp_update_user._user_id
AND _user_info ?| '{firstname,lastname}';
IF FOUND THEN
RETURN '{"success":true}'::jsonb;
ELSE
RETURN '{"success":false}'::jsonb;
END IF;
END
$func$ LANGUAGE plpgsql;
ये कॉल अब उम्मीद के मुताबिक काम करती हैं:
SELECT sp_update_user(123, '{"firstname": null, "lastname": "doe1"}'::jsonb);
SELECT sp_update_user(123, '{"firstname": "doris"}'::jsonb);