Dein Beispiel ist kaputt. Quelle und Ziel sind in Ihrem INSERT
gleich im Auslöser, der zwangsläufig jedes Mal einen eindeutigen Verstoß auslösen wird (außer beim Einfügen von NULL) - unterdrückt durch ON CONFLICT (test_name2) DO NOTHING
, sodass im Trigger niemals etwas passiert.
Sie vergessen auch die Eindeutigkeitsbeschränkung in Ihrem ursprünglichen INSERT
. Siehe unten.
INSERT INTO test2(test_name2)
VALUES(NEW.test_name2)
...
CREATE TRIGGER trigger_test
AFTER INSERT
ON test2
Beginnen Sie mit einem weniger verwirrenden Setup:
CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);
Und es ist effizienter, test1
eingefügt wurden zu test2
(und nicht umgekehrt), nur für das erste Level der Triggertiefe:
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;
Ich habe es als AFTER
beibehalten Abzug. Kann ein BEFORE
sein Trigger auch, aber dort würden Sie brauchen RETURN NEW;
.
CREATE TRIGGER trigger_test
AFTER INSERT ON test1 -- !!
FOR EACH ROW
WHEN (pg_trigger_depth() < 1) -- !!
EXECUTE PROCEDURE trig_test();
Warum (pg_trigger_depth() <1)
?
Hinweis dass Sie eindeutige Verstöße in test2
abfangen auf diese Weise (es passiert nichts), aber eindeutige Verletzungen in test1
würde immer noch eine Ausnahme auslösen, es sei denn, Sie haben ON CONFLICT ... DO NOTHING
dort genauso. Ihr Test ist Wunschdenken:
Muss sein:
INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;
Alternative:Zwei INSERT
verketten mit einem CTE
Wenn Sie die Kontrolle über INSERT
haben Befehle auf test1
, können Sie dies anstelle des Triggers tun:
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;
Verwandte:
- Fügen Sie mit Postgres Daten in 3 Tabellen gleichzeitig ein
- PostgreSQL-Multi-INSERT. ..RETURNING mit mehreren Spalten