PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

जांचें कि क्या JSON में PL/pgSQL के साथ कुंजी मौजूद है?

आपने पहले ही पाया है कि आप अभिव्यक्ति का परीक्षण कर सकते हैं 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 पर सेट है , आपको एक SQL NULL भी मिलता है परिणाम के रूप में। विचार करें:

    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);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JOOQ PostgreSQL कस्टम प्रकार के साथ एक सरणी के रूप में विफल रहता है:त्रुटि:विकृत रिकॉर्ड शाब्दिक

  2. आईओएस एसडीके 4.2 के साथ libpq संकलित करना

  3. स्ट्रिंग मानों में अल्पविराम के साथ CSV आयात करना

  4. PostgreSQL कॉलम मान एक क्रम में होना चाहिए

  5. जांचें कि क्या sqlalchemy तालिका खाली है