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

Gør intet i en triggerprocedure

Dit eksempel er brudt. Kilde og mål er de samme i din INSERT i udløseren, hvilket er bundet til at rejse en unik overtrædelse hver gang (undtagen ved indsættelse af NULL) - undertrykt af ON CONFLICT (test_name2) DO NOTHING , så der sker aldrig noget i aftrækkeren.

Du glemmer også den unikke begrænsning i din originale INSERT . Se nedenfor.

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

...

CREATE TRIGGER trigger_test
AFTER INSERT
ON test2

Start med en mindre forvirrende opsætning:

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

Og det er mere effektivt at flytte pg_trigger_depth() til selve udløseren. Så dette ville fungere, kopiering af rækker indsat i test1 til test2 (og ikke omvendt), kun for den første niveau af triggerdybde:

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;

Jeg beholdt det som AFTER udløser. Kan være en BEFORE trigger også, men der skal du bruge RETURN NEW; .

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

Hvorfor (pg_trigger_depth() < 1) ?

Bemærk at du fanger unikke overtrædelser i test2 denne måde (der sker intet), men unikke overtrædelser i test1 ville stadig rejse en undtagelse, medmindre du har ON CONFLICT ... DO NOTHING der også. Din test er ønsketænkning:

Skal være:

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

Alternativ:Kæde to INSERT med en CTE

Hvis du har kontrol over INSERT kommandoer på test1 , kan du gøre dette i stedet for triggeren:

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;

Relateret:




  1. mysql:vælg alle elementer fra tabel A, hvis de ikke findes i tabel B

  2. MySQL – Sådan genereres tilfældigt tal

  3. Introduktion til PL/SQL VARRAY'er i Oracle-databasen

  4. PHP og MySQL - Tjek om brugernavnet allerede er taget