sql >> Databáze >  >> RDS >> PostgreSQL

Nedělejte nic ve spouštěcí proceduře

Váš příklad je nefunkční. Zdroj a cíl jsou ve vašem INSERT stejné ve spouštěči, což nutně vyvolá jedinečné porušení pokaždé (kromě vložení NULL) - potlačeno pomocí ON CONFLICT (test_name2) DO NOTHING , takže se ve spouštěči nikdy nic nestane.

Také zapomenete na jedinečné omezení ve svém původním INSERT . Viz níže.

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

...

CREATE TRIGGER trigger_test
AFTER INSERT
ON test2

Začněte s méně matoucím nastavením:

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

A je efektivnější přesunout pg_trigger_depth() na samotnou spoušť. Takže by to fungovalo, kopírování řádků vložených do test1 na test2 (a ne naopak), pouze pro první úroveň hloubky spouštění:

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;

Nechal jsem to jako AFTER spoušť. Může být BEFORE spouště také, ale tam byste potřebovali RETURN NEW; .

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

Proč (pg_trigger_depth() < 1) ?

Poznámka že zachytíte jedinečná porušení v test2 tímto způsobem (nic se nestane), ale jedinečná porušení v test1 by stále vyvolalo výjimku, pokud nemáte ON CONFLICT ... DO NOTHING tam také. Váš test je zbožné přání:

Musí být:

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

Alternativa:Řetězec dvě INSERT s CTE

Pokud máte kontrolu nad INSERT příkazy na test1 , můžete to udělat místo spouštěče:

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;

Související:




  1. Oracle Connections a VS2012

  2. Která verze MySQL je kompatibilní s Airflow verze 1.10?

  3. Jak přiřadím celý den k poli datum a čas?

  4. Více rozbalovacích hodnot vkládání do jednoho řádku, nikoli do více řádků