sql >> Database >  >> RDS >> PostgreSQL

Niets doen in een triggerprocedure

Je voorbeeld is gebroken. Bron en doel zijn hetzelfde in uw INSERT in de trigger, die zeker elke keer een unieke overtreding zal opleveren (behalve bij het invoegen van NULL) - onderdrukt door ON CONFLICT (test_name2) DO NOTHING , dus er gebeurt nooit iets in de trigger.

Je vergeet ook de unieke beperking in je originele INSERT . Zie hieronder.

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

...

CREATE TRIGGER trigger_test
AFTER INSERT
ON test2

Begin met een minder verwarrende setup:

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

En het is efficiënter om pg_trigger_depth() naar de trekker zelf. Dus dit zou werken, rijen kopiëren die zijn ingevoegd in test1 naar test2 (en niet andersom), alleen voor de eerste niveau van triggerdiepte:

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;

Ik heb het bewaard als AFTER trekker. Kan een BEFORE . zijn trigger ook, maar daar heb je nodig RETURN NEW; .

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

Waarom (pg_trigger_depth() < 1) ?

Opmerking dat u unieke schendingen in test2 trap opspoort op deze manier (er gebeurt niets), maar unieke overtredingen in test1 zou nog steeds een uitzondering maken, tenzij je ON CONFLICT ... DO NOTHING daar ook. Je test is wishful thinking:

Moet zijn:

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

Alternatief:ketting twee INSERT met een CTE

Als je controle hebt over INSERT commando's op test1 , kunt u dit doen in plaats van de 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;

Gerelateerd:




  1. HTML-reactie krijgen in plaats van JSON in Android

  2. PostgreSQL FOUT:42P01:relatie [Tabel] bestaat niet

  3. Een van de kolommen in een samengestelde sleutel als externe sleutel gebruiken

  4. Kan de door de login gevraagde databasetest niet openen. Het inloggen is mislukt. Inloggen mislukt voor gebruiker 'xyz\ASPNET'