यदि कोई "स्रोत" "पहचानकर्ता नहीं भेजता है", तो कॉलम अपरिवर्तित रहेगा। तब आप यह पता नहीं लगा सकते कि वर्तमान 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;
बाकी को उसी के अनुसार ढालें।