आपका उदाहरण टूटा हुआ है। स्रोत और लक्ष्य आपके INSERT
. में समान हैं ट्रिगर में, जो हर बार एक अद्वितीय उल्लंघन करने के लिए बाध्य है (NULL डालने के अलावा) - ON CONFLICT (test_name2) DO NOTHING
, इसलिए ट्रिगर में कभी कुछ नहीं होता है।
आप अपने मूल INSERT
. में अद्वितीय बाधा के बारे में भी भूल जाते हैं . नीचे देखें।
INSERT INTO test2(test_name2)
VALUES(NEW.test_name2)
...
CREATE TRIGGER trigger_test
AFTER INSERT
ON test2
कम भ्रमित करने वाले सेटअप से शुरू करें:
CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);
और pg_trigger_depth()
ट्रिगर को ही। तो यह काम करेगा, test1
. में डाली गई पंक्तियों की प्रतिलिपि बनाना करने के लिए test2
(और दूसरे तरीके से नहीं), केवल पहले . के लिए ट्रिगर गहराई का स्तर:
CREATE OR REPLACE FUNCTION trig_test()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO test2(col2) -- !!
VALUES (NEW.col1) -- !!
ON CONFLICT (col2) DO NOTHING; -- !!
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
मैंने इसे AFTER
. के रूप में रखा है चालू कर देना। एक BEFORE
हो सकता है ट्रिगर भी, लेकिन वहां आपको ज़रूरत होगी RETURN NEW;
।
CREATE TRIGGER trigger_test
AFTER INSERT ON test1 -- !!
FOR EACH ROW
WHEN (pg_trigger_depth() < 1) -- !!
EXECUTE PROCEDURE trig_test();
क्यों (pg_trigger_depth() < 1)
?
नोट कि आप अद्वितीय उल्लंघनों को test2
. में फंसाते हैं इस तरह (कुछ नहीं होता), लेकिन test1
. में अद्वितीय उल्लंघन जब तक आपके पास ON CONFLICT ... DO NOTHING
. तब तक अपवाद नहीं उठाएंगे वहाँ भी है। आपका परीक्षण इच्छाधारी सोच है:
होना चाहिए:
INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;
वैकल्पिक:चेन दो INSERT
सीटीई के साथ
यदि आपके पास INSERT
. पर नियंत्रण है test1
. पर कमांड , आप ट्रिगर के बजाय ऐसा कर सकते हैं:
WITH ins1 AS (
INSERT INTO test1(col1)
VALUES ('foo') -- your value goes here
ON CONFLICT (col1) DO NOTHING
RETURNING *
)
INSERT INTO test2(col2)
SELECT col1 FROM ins1
ON CONFLICT (col2) DO NOTHING;
संबंधित:
- Postgres का उपयोग करके एक बार में 3 तालिकाओं में डेटा सम्मिलित करें
- PostgreSQL मल्टी INSERT। ..एकाधिक कॉलम के साथ वापसी