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

PostgreSQL ट्रिगर्स को यूजर आईडी पास करना

विकल्पों में शामिल हैं:

  • जब आप कोई कनेक्शन खोलते हैं, CREATE TEMPORARY TABLE current_app_user(username text); INSERT INTO current_app_user(username) VALUES ('the_user'); . फिर अपने ट्रिगर में, SELECT username FROM current_app_user वर्तमान उपयोगकर्ता नाम प्राप्त करने के लिए, संभवतः एक सबक्वेरी के रूप में।

  • postgresql.conf . में कस्टम जीयूसी के लिए एक प्रविष्टि बनाएं जैसे my_app.username = 'unknown'; . जब भी आप कोई कनेक्शन बनाएं SET my_app.username = 'the_user'; . चलाएं . फिर ट्रिगर में, current_setting('my_app.username') . का उपयोग करें मान प्राप्त करने के लिए कार्य करता है। प्रभावी रूप से, आप सत्र चर प्रदान करने के लिए GUC मशीनरी का दुरुपयोग कर रहे हैं। अपने सर्वर संस्करण के लिए उपयुक्त दस्तावेज़ पढ़ें, क्योंकि 9.2 में कस्टम जीयूसी बदल गए हैं

  • अपने एप्लिकेशन को समायोजित करें ताकि इसमें प्रत्येक एप्लिकेशन उपयोगकर्ता के लिए डेटाबेस भूमिकाएं हों। SET ROLE काम करने से पहले उस उपयोगकर्ता को। यह न केवल आपको बिल्ट-इन current_user . का उपयोग करने देता है SELECT current_user; . के लिए चर-समान फ़ंक्शन , यह आपको डेटाबेस में सुरक्षा लागू करने . की भी अनुमति देता है . यह प्रश्न देखें। आप SET ROLE . का उपयोग करने के बजाय सीधे उपयोगकर्ता के रूप में लॉग इन कर सकते हैं , लेकिन यह कनेक्शन पूलिंग को कठिन बना देता है।

दोनों ही मामलों में आप कनेक्शन पूलिंग कर रहे हैं, आपको DISCARD ALL; के प्रति सावधान रहना चाहिए। जब आप पूल से कनेक्शन वापस करते हैं। (यद्यपि इसे ऐसा करने के रूप में प्रलेखित नहीं किया गया है, DISCARD ALL एक RESET ROLE करता है )।

डेमो के लिए सामान्य सेटअप:

CREATE TABLE tg_demo(blah text);
INSERT INTO tg_demo(blah) VALUES ('spam'),('eggs');

-- Placeholder; will be replaced by demo functions
CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
SELECT 'unknown';
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION tg_demo_trigger() RETURNS trigger AS $$
BEGIN
    RAISE NOTICE 'Current user is: %',get_app_user();
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tg_demo_tg
AFTER INSERT OR UPDATE OR DELETE ON tg_demo 
FOR EACH ROW EXECUTE PROCEDURE tg_demo_trigger();

जीयूसी का उपयोग करना:

  • CUSTOMIZED OPTIONS में postgresql.conf . का अनुभाग , myapp.username = 'unknown_user' . जैसी लाइन जोड़ें . 9.2 से पुराने PostgreSQL संस्करणों पर आपको custom_variable_classes = 'myapp' भी सेट करना होगा ।
  • PostgreSQL को पुनरारंभ करें। अब आप SHOW myapp.username . में सक्षम होंगे और मान प्राप्त करें unknown_user

अब आप SET myapp.username = 'the_user'; . का उपयोग कर सकते हैं जब आप कोई कनेक्शन स्थापित करते हैं, या वैकल्पिक रूप से SET LOCAL myapp.username = 'the_user'; BEGIN . के बाद यदि आप लेन-देन-स्थानीय बनाना चाहते हैं, जो पूल किए गए कनेक्शन के लिए सुविधाजनक है, तो लेन-देन करना।

get_app_user फ़ंक्शन परिभाषा:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
    SELECT current_setting('myapp.username');
$$ LANGUAGE sql;

SET LOCAL . का उपयोग करके डेमो लेन-देन-स्थानीय वर्तमान उपयोगकर्ता नाम के लिए:

regress=> BEGIN;
BEGIN
regress=> SET LOCAL myapp.username = 'test_user';
SET
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: test_user
INSERT 0 1
regress=> COMMIT;
COMMIT
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

अगर आप SET . का इस्तेमाल करते हैं SET LOCAL . के बजाय सेटिंग प्रतिबद्ध/रोलबैक समय पर वापस नहीं आएगी, इसलिए यह पूरे सत्र में बनी रहती है। यह अभी भी DISCARD ALL . द्वारा रीसेट किया गया है :

regress=> SET myapp.username = 'test';
SET
regress=> SHOW myapp.username;
 myapp.username 
----------------
 test
(1 row)

regress=> DISCARD ALL;
DISCARD ALL
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

साथ ही, ध्यान दें कि आप SET . का उपयोग नहीं कर सकते हैं या SET LOCAL सर्वर-साइड बाइंड पैरामीटर के साथ। यदि आप बाइंड पैरामीटर ("तैयार कथन") का उपयोग करना चाहते हैं, तो फ़ंक्शन फ़ॉर्म set_config(...) का उपयोग करने पर विचार करें . सिस्टम व्यवस्थापन कार्य देखें

अस्थायी तालिका का उपयोग करना

इस दृष्टिकोण के लिए एक ट्रिगर (या ट्रिगर द्वारा बुलाए गए सहायक फ़ंक्शन, अधिमानतः) के उपयोग की आवश्यकता होती है जो प्रत्येक सत्र में एक अस्थायी तालिका से एक मान को पढ़ने का प्रयास करता है। यदि अस्थायी तालिका नहीं मिल सकती है, तो एक डिफ़ॉल्ट मान प्रदान किया जाता है। यह कुछ धीमा होने की संभावना है . ध्यान से परीक्षण करें।

get_app_user() परिभाषा:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
DECLARE
    cur_user text;
BEGIN
    BEGIN
        cur_user := (SELECT username FROM current_app_user);
    EXCEPTION WHEN undefined_table THEN
        cur_user := 'unknown_user';
    END;
    RETURN cur_user;
END;
$$ LANGUAGE plpgsql VOLATILE;

डेमो:

regress=> CREATE TEMPORARY TABLE current_app_user(username text);
CREATE TABLE
regress=> INSERT INTO current_app_user(username) VALUES ('testuser');
INSERT 0 1
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: testuser
INSERT 0 1
regress=> DISCARD ALL;
DISCARD ALL
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: unknown_user
INSERT 0 1

सुरक्षित सत्र चर

PostgreSQL में "सुरक्षित सत्र चर" जोड़ने का भी प्रस्ताव है। ये पैकेज वेरिएबल की तरह थोड़े हैं। PostgreSQL 12 के रूप में इस सुविधा को शामिल नहीं किया गया है, लेकिन नज़र रखें और हैकर्स सूची पर बोलें यदि यह कुछ ऐसा है जिसकी आपको आवश्यकता है।

उन्नत:साझा स्मृति क्षेत्र के साथ आपका अपना एक्सटेंशन

उन्नत उपयोगों के लिए आप अपने स्वयं के सी एक्सटेंशन को एक साझा मेमोरी क्षेत्र पंजीकृत कर सकते हैं और सी फ़ंक्शन कॉल का उपयोग करके बैकएंड के बीच संवाद कर सकते हैं जो डीएसए सेगमेंट में मूल्यों को पढ़ते/लिखते हैं। विवरण के लिए PostgreSQL प्रोग्रामिंग उदाहरण देखें। आपको C ज्ञान, समय और धैर्य की आवश्यकता होगी।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pgadmin4 :postgresql एप्लिकेशन सर्वर से संपर्क नहीं किया जा सका।

  2. स्व-हस्ताक्षरित प्रमाणपत्रों के साथ जंग में PostgreSQL SSL कनेक्शन का उपयोग करें

  3. PostgreSQL के साथ उत्पादन में जाने के लिए दस युक्तियाँ

  4. Postgres में टाइमस्टैम्प को 5 मिनट तक छोटा करने का सबसे तेज़ तरीका क्या है?

  5. SQL जहां शामिल हुए सेट में सभी मान होने चाहिए लेकिन अधिक हो सकते हैं