PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Non fare nulla in una procedura di attivazione

Il tuo esempio è rotto. Sorgente e destinazione sono le stesse nel tuo INSERT nel trigger, che è destinato a generare una violazione unica ogni volta (tranne quando si inserisce NULL) - soppresso da ON CONFLICT (test_name2) DO NOTHING , quindi non succede mai nulla nel trigger.

Ti dimentichi anche del vincolo univoco nel tuo INSERT originale . Vedi sotto.

INSERT INTO test2(test_name2)
   VALUES(NEW.test_name2)

...

CREATE TRIGGER trigger_test
AFTER INSERT
ON test2

Inizia con una configurazione meno confusa:

CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);

Ed è più efficiente spostare pg_trigger_depth() al grilletto stesso. Quindi funzionerebbe, copiando le righe inserite in test1 a test2 (e non il contrario), solo per il primo livello di profondità del trigger:

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;

L'ho tenuto come AFTER grilletto. Può essere un BEFORE trigger anche, ma lì avresti necessario RETURN NEW; .

CREATE TRIGGER trigger_test
AFTER INSERT ON test1                  -- !!
FOR EACH ROW 
WHEN (pg_trigger_depth() < 1)          -- !!
EXECUTE PROCEDURE trig_test();

Perché (pg_trigger_depth() < 1) ?

Nota che intrappoli le violazioni uniche in test2 in questo modo (non succede nulla), ma violazioni uniche in test1 solleverebbe comunque un'eccezione a meno che tu non abbia ON CONFLICT ... DO NOTHING anche lì. Il tuo test è un pio desiderio:

Deve essere:

INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;

Alternativa:concatena due INSERT con un CTE

Se hai il controllo su INSERT comandi su test1 , puoi farlo invece del trigger:

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;

Correlati: