Votre exemple est cassé. La source et la cible sont les mêmes dans votre INSERT
dans le déclencheur, qui est lié à déclencher une violation unique à chaque fois (sauf lors de l'insertion de NULL) - supprimé par ON CONFLICT (test_name2) DO NOTHING
, donc rien ne se passe jamais dans le déclencheur.
Vous oubliez également la contrainte unique dans votre INSERT
d'origine . Voir ci-dessous.
INSERT INTO test2(test_name2)
VALUES(NEW.test_name2)
...
CREATE TRIGGER trigger_test
AFTER INSERT
ON test2
Commencez par une configuration moins déroutante :
CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);
Et il est plus efficace de déplacer pg_trigger_depth()
au déclencheur lui-même. Donc, cela fonctionnerait, en copiant les lignes insérées dans test1
à test2
(et non l'inverse), uniquement pour le premier niveau de profondeur de déclenchement :
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;
Je l'ai gardé comme AFTER
gâchette. Peut être un BEFORE
déclencher également, mais là, vous auriez besoin RETURN NEW;
.
CREATE TRIGGER trigger_test
AFTER INSERT ON test1 -- !!
FOR EACH ROW
WHEN (pg_trigger_depth() < 1) -- !!
EXECUTE PROCEDURE trig_test();
Pourquoi (pg_trigger_depth() < 1)
?
Remarque que vous interceptez des violations uniques dans test2
de cette façon (rien ne se passe), mais des violations uniques dans test1
soulèverait toujours une exception à moins que vous n'ayez ON CONFLICT ... DO NOTHING
là aussi. Votre test est un vœu pieux :
Doit être :
INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;
Alternative :chaînez deux INSERT
avec un CTE
Si vous contrôlez INSERT
commandes sur test1
, vous pouvez le faire à la place du déclencheur :
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;
Connexe :
- Insérer des données dans 3 tables à la fois en utilisant Postgres
- PostgreSQL multi INSERT. ..RETURNING avec plusieurs colonnes