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

एक ट्रिगर फ़ंक्शन के भीतर, कैसे प्राप्त करें कि कौन से फ़ील्ड अपडेट किए जा रहे हैं

यदि कोई "स्रोत" "पहचानकर्ता नहीं भेजता है", तो कॉलम अपरिवर्तित रहेगा। तब आप यह पता नहीं लगा सकते कि वर्तमान UPDATE पिछले स्रोत के समान स्रोत द्वारा या किसी ऐसे स्रोत द्वारा किया गया था जिसने कॉलम को बिल्कुल भी नहीं बदला था। दूसरे शब्दों में:यह ठीक से काम नहीं करता है।

यदि "स्रोत" किसी सत्र सूचना फ़ंक्शन द्वारा पहचाना जा सकता है, तो आप उसके साथ काम कर सकते हैं। पसंद:

NEW.column = session_user;

हर अपडेट के लिए बिना शर्त।

सामान्य समाधान

मुझे मूल समस्या को हल करने का एक तरीका मिला। कॉलम को किसी भी . में डिफ़ॉल्ट मान पर सेट किया जाएगा अपडेट करें जहां कॉलम अपडेट नहीं है (SET . में नहीं UPDATE की सूची )।

मुख्य तत्व एक प्रति-स्तंभ ट्रिगर . है PostgreSQL 9.0 में पेश किया गया - UPDATE OF . का उपयोग करके एक कॉलम-विशिष्ट ट्रिगर column_name खंड।

<ब्लॉकक्वॉट>

ट्रिगर केवल तभी सक्रिय होगा जब सूचीबद्ध स्तंभों में से कम से कम एक का उल्लेख UPDATE के लक्ष्य के रूप में किया गया हो आदेश।

यही एकमात्र सरल तरीका है जिससे मैंने पाया कि क्या किसी स्तंभ को पुराने के समान नए मान के साथ अद्यतन किया गया था, बनाम बिल्कुल भी अद्यतन नहीं किया गया था।

एक कर सकता था current_query() by द्वारा लौटाए गए टेक्स्ट को भी पार्स करें . लेकिन यह मुश्किल और अविश्वसनीय लगता है।

ट्रिगर फ़ंक्शन

मुझे लगता है कि एक कॉलम col . है परिभाषित NOT NULL

चरण 1: col सेट करें करने के लिए NULL अगर अपरिवर्तित:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step1()
  RETURNS trigger AS
$func$
BEGIN
   IF OLD.col = NEW.col THEN
      NEW.col := NULL;      -- "impossible" value
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

चरण 2: पुराने मान पर वापस जाएँ। ट्रिगर केवल तभी सक्रिय किया जाएगा, जब मान वास्तव में अपडेट किया गया हो (नीचे देखें):

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step2()
  RETURNS trigger AS
$func$
BEGIN
   IF NEW.col IS NULL THEN
      NEW.col := OLD.col;
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

चरण 3: अब हम अनुपलब्ध अद्यतन की पहचान कर सकते हैं और इसके बजाय एक डिफ़ॉल्ट मान सेट कर सकते हैं:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step3()
  RETURNS trigger AS
$func$
BEGIN
   IF NEW.col IS NULL THEN
      NEW.col := 'default value';
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

ट्रिगर

चरण 2 . के लिए ट्रिगर प्रति कॉलम सक्रिय है!

CREATE TRIGGER upbef_step1
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step1();

CREATE TRIGGER upbef_step2
  BEFORE UPDATE OF col ON tbl                -- key element!
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step2();

CREATE TRIGGER upbef_step3
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step3();

ट्रिगर नाम प्रासंगिक हैं, क्योंकि उन्हें वर्णानुक्रम में सक्रिय किया गया है (सभी BEFORE UPDATE . हैं )!

प्रक्रिया को "प्रति-नहीं-स्तंभ ट्रिगर" या किसी UPDATE की लक्ष्य-सूची की जांच करने के किसी अन्य तरीके से सरल बनाया जा सकता है एक ट्रिगर में। लेकिन मुझे इसके लिए कोई संभाल नहीं दिख रहा है।

अगर col NULL हो सकता है , किसी अन्य "असंभव" मध्यवर्ती मान का उपयोग करें और NULL . की जांच करें अतिरिक्त रूप से ट्रिगर फ़ंक्शन 1 में:

IF OLD.col IS NOT DISTINCT FROM NEW.col THEN
    NEW.col := '#impossible_value#';
END IF;

बाकी को उसी के अनुसार ढालें।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django + Postgres + बड़ी समय श्रृंखला

  2. DLL 'kernel32.dll' में 'InterlockedIncrement' नाम का एंट्री पॉइंट ढूंढने में असमर्थ - [ईमेल संरक्षित] 64 बिट

  3. कैसे psql के भीतर से एक postgresql डेटाबेस का बैकअप लेने के लिए?

  4. टाइमस्टैम्प के विरुद्ध प्रारंभ और समाप्ति समय के बीच PostgreSQL मिलान अंतराल

  5. PostgreSQL में अग्रणी शून्य जोड़ने के 2 तरीके