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

ट्रिगर फ़ंक्शन में गतिशील तालिका नाम के साथ INSERT

PostgreSQL 9.1 या बाद के संस्करण

format() पहचानकर्ताओं से बचने का एक अंतर्निहित तरीका है। पहले से आसान:

CREATE OR REPLACE FUNCTION foo_before()
  RETURNS trigger AS
$func$
BEGIN
   EXECUTE format('INSERT INTO %I.%I SELECT $1.*'
                , TG_TABLE_SCHEMA, TG_TABLE_NAME || 'shadow')
   USING OLD;

   RETURN OLD;
END
$func$  LANGUAGE plpgsql;

VALUES . के साथ काम करता है अभिव्यक्ति भी।

db<>फिडल यहाँ
पुराना sqlfiddle.

प्रमुख बिंदु

  • format() का उपयोग करें या quote_ident() पहचानकर्ताओं को उद्धृत करने के लिए (स्वचालित रूप से और केवल जहां आवश्यक हो), जिससे SQL इंजेक्शन और सरल वाक्यविन्यास उल्लंघनों से बचाव हो सके।
    यह आवश्यक है , यहां तक ​​कि आपके अपने टेबल नामों के साथ भी!
  • स्कीमा-तालिका नाम योग्य। वर्तमान search_path . के आधार पर एक नंगे टेबल नाम को सेट करना अन्यथा एक ही नाम की दूसरी तालिका को एक अलग स्कीमा में हल कर सकता है।
  • EXECUTE का प्रयोग करें डायनामिक डीडीएल स्टेटमेंट के लिए।
  • पास मान USING . के साथ सुरक्षित रूप से खंड।
  • plpgsql में डायनेमिक कमांड निष्पादित करने पर बारीक मैनुअल से परामर्श लें।
  • ध्यान दें किRETURN OLD; ट्रिगर फ़ंक्शन में एक ट्रिगर के लिए आवश्यक है BEFORE DELETE . मैनुअल में विवरण यहाँ।

आपको त्रुटि संदेश . मिलता है आपके लगभग सफल संस्करण में क्योंकि OLD दिखाई नहीं दे रहा है अंदर EXECUTE . और यदि आप अपनी कोशिश की तरह विघटित पंक्ति के अलग-अलग मानों को जोड़ना चाहते हैं, तो आपको quote_literal() के साथ प्रत्येक कॉलम का टेक्स्ट प्रस्तुतिकरण तैयार करना होगा। वैध वाक्यविन्यास की गारंटी के लिए। आपको जानना . भी होगा कॉलम नाम पहले से ही उन्हें संभालने या सिस्टम कैटलॉग को क्वेरी करने के लिए - जो एक सरल, गतिशील ट्रिगर फ़ंक्शन रखने के आपके विचार के विरुद्ध है ...

मेरा समाधान इन सभी जटिलताओं से बचाता है। थोड़ा सरल भी किया।

PostgreSQL 9.0 या इससे पहले का

format() अभी तक उपलब्ध नहीं है, इसलिए:

CREATE OR REPLACE FUNCTION foo_before()
  RETURNS trigger AS
$func$
BEGIN
    EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA)
                    || '.' || quote_ident(TG_TABLE_NAME || 'shadow')
                    || ' SELECT $1.*'
    USING OLD;

    RETURN OLD;
END
$func$  LANGUAGE plpgsql;

संबंधित:

  • PostgreSQL 8.2 में TG_TABLE_NAME का गतिशील रूप से उपयोग कैसे करें?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में एसिंक्रोनस से सिंक्रोनस प्रतिकृति में कनवर्ट करना

  2. Postgresql DB का उपयोग करके NULL मान को संग्रहीत करने के लिए कितने डिस्क-स्थान की आवश्यकता है?

  3. मेरे MySQL डीबी के लिए काम नहीं कर रहे लेनदेन

  4. बूलियन कॉलम पर SQLAlchemy func.count

  5. पोस्टग्रेस्क्ल में महीने और साल के अनुसार समूह क्वेरी परिणाम