यदि आप अपने कोड को संशोधित करने से बचाना चाहते हैं और फ़ंक्शन NULL
त्रुटि पर वापस लौटना चाहते हैं, तो आप उन्हें पीएल/पीजीएसक्यूएल फ़ंक्शन में लपेटकर ऐसा कर सकते हैं जो त्रुटि को फँसाने के लिए BEGIN ... EXCEPTION
ब्लॉक का उपयोग करता है।
ऐसा करने के लिए, पहले मैं त्रुटि के लिए SQLSTATE मिलती है:
regress=# \set VERBOSITY verbose
regress=# SELECT pgp_sym_decrypt('fred','key');
ERROR: 39000: Wrong key or corrupt data
LOCATION: decrypt_internal, pgp-pgsql.c:607
मैं त्रुटि हैंडलर में सीधे इस इस्तेमाल कर सकते हैं, लेकिन मैं एक प्रतीकात्मक नाम का उपयोग करना पसंद है, इसलिए मैं त्रुटि नाम ऊपर देखो Appendix A - Error codes में 3 9 000 से जुड़े, यह पता चलता है कि यह जेनेरिक फ़ंक्शन कॉल त्रुटि external_routine_invocation_exception
है। जैसा कि हम पसंद करेंगे उतना विशिष्ट नहीं है, लेकिन यह करेगा।
अब एक रैपर फ़ंक्शन आवश्यक है। इस तरह कुछ कुछ परिभाषित किया जाना चाहिए, pgp_sym_decrypt
के प्रत्येक ओवरलोडेड हस्ताक्षर के लिए एक फ़ंक्शन के साथ जिसे आप समर्थन देना चाहते हैं। (bytea,text)
रूप है कि text
देता है, उदाहरण के लिए के लिए:
CREATE OR REPLACE FUNCTION pgp_sym_decrypt_null_on_err(data bytea, psw text) RETURNS text AS $$
BEGIN
RETURN pgp_sym_decrypt(data, psw);
EXCEPTION
WHEN external_routine_invocation_exception THEN
RAISE DEBUG USING
MESSAGE = format('Decryption failed: SQLSTATE %s, Msg: %s',
SQLSTATE,SQLERRM),
HINT = 'pgp_sym_encrypt(...) failed; check your key',
ERRCODE = 'external_routine_invocation_exception';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
मैं एक DEBUG
स्तर संदेश में मूल त्रुटि preseve के लिए चुना है। पूर्ण संदेश शब्दकोष और डीबग स्तर आउटपुट के साथ मूल और रैपर की तुलना यहां दी गई है।
RAISE
दिखाने के लिए डीबग आउटपुट सक्षम करें। ध्यान दें कि यह पैरामीटर समेत pgp_decrypt_sym
कॉल के * मूल क्वेरी टेक्स्ट को भी दिखाता है।
regress=# SET client_min_messages = DEBUG;
न्यू समारोह अभी भी त्रुटि की रिपोर्ट करने पर विस्तृत लॉगिंग सक्षम है लिपटे, लेकिन NULL
रिटर्न:
regress=# SELECT pgp_sym_decrypt_null_on_err('redsdfsfdsfd','bobsdf');
LOG: 00000: statement: SELECT pgp_sym_decrypt_null_on_err('redsdfsfdsfd','bobsdf');
LOCATION: exec_simple_query, postgres.c:860
DEBUG: 39000: Decryption failed: SQLSTATE 39000, Msg: Wrong key or corrupt data
HINT: pgp_sym_encrypt(...) failed; check your key
LOCATION: exec_stmt_raise, pl_exec.c:2806
pgp_sym_decrypt_null_on_err
-----------------------------
(1 row)
मूल है, जो विफल रहता है की तुलना में:
regress=# SELECT pgp_sym_decrypt('redsdfsfdsfd','bobsdf');
LOG: 00000: statement: SELECT pgp_sym_decrypt('redsdfsfdsfd','bobsdf');
LOCATION: exec_simple_query, postgres.c:860
ERROR: 39000: Wrong key or corrupt data
LOCATION: decrypt_internal, pgp-pgsql.c:607
ध्यान दें कि दोनों फॉर्म विफल होने पर फ़ंक्शन को कॉल किए जाने वाले पैरामीटर दिखाते हैं। यदि आप बाइंड पैरामीटर ("तैयार कथन") का उपयोग करते हैं तो पैरामीटर नहीं दिखाए जाएंगे, लेकिन यदि आप इन-डेटाबेस एन्क्रिप्शन का उपयोग कर रहे हैं तो आपको अभी भी अपने लॉग को सुरक्षा महत्वपूर्ण मानना चाहिए।
व्यक्तिगत रूप से, मुझे लगता है कि ऐप में क्रिप्टो करना बेहतर है, इसलिए डीबी को कभी भी चाबियों तक पहुंच नहीं है।
आपके उत्तर के लिए धन्यवाद।मैंने अंतिम उपाय के रूप में इस तरह के एक समारोह को लागू करने के लिए जाने का फैसला किया है। वास्तव में बहुत उपयोगी है। मैं इन-बिल्डिंग pgsql फ़ंक्शंस से अधिकतम प्राप्त करने का प्रयास कर रहा हूं। मुझे देखने दो कि यह कैसे मदद करता है। ऐप में सभी क्रिप्टो करने के आपके सुझाव के लिए भी धन्यवाद .. इस तरह मैंने ऐप में कुछ महत्वपूर्ण कार्यक्षमताओं को बदलने की योजना बनाई है। मैं बाद में सबकुछ बदल दूंगा .. –
@ user1365983 अच्छा - मुझे नहीं लगता कि यह एक बहुत अच्छा विचार है, इसलिए मुझे खुशी है कि आप इसे करने की योजना नहीं बना रहे हैं। ऊपरी बाईं ओर दिए गए उत्तर स्कोर के नीचे टिक का उपयोग करके, अगर यह मददगार था, तो कृपया उत्तर स्वीकार करें। –