sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur får man PostgreSQL att infoga en rad i en tabell när den tas bort från en annan tabell?

Skriv en triggerfunktion. Något så här:

CREATE OR REPLACE FUNCTION trg_backup_row()
  RETURNS trigger AS
$BODY$
BEGIN

INSERT INTO other_tbl
SELECT (OLD).*, t.other_col                -- all columns of from old table
-- SELECT OLD.col1, OLD.col2, t.other_col  -- alternative: some cols from old tbl
FROM   third_tbl t
WHERE  t.col = OLD.col  -- link to third table with info from deleted row
AND    <unique_condition_to_avoid_multiple_rows_if_needed>;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Och en trigger ON DELETE . Så här:

CREATE TRIGGER delaft
  AFTER DELETE
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_backup_row();

Nyckelelement

  • Bäst gör det till en utlösare AFTER DELETE och FOR EACH ROW .

  • För att returnera alla kolumner från den gamla tabellen använd syntaxen (OLD).* . Se manualen om åtkomst av sammansatta typer . Alternativt OLD.* är också giltig syntax eftersom OLD läggs till i FROM klausul implicit. För en VALUES uttryck det måste vara (OLD).* , fastän. Gilla:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Du kan inkludera värden från vilken annan tabell som helst som jag visar. Se bara till att få en enda rad, annars skapar du flera poster.

  • När utlösaren aktiveras AFTER händelsen kan funktionen RETURN NULL .

Om synlighet

Som svar på @coulings vaksamma kommentar.

Medan främmande nycklar kan deklareras som DEFERRED kod> , kommer detta bara att skjuta upp integritetskontrollen, inte själva borttagningen. Rader som raderas i triggers som exekveras före den aktuella eller av ON DELETE CASCADE främmande nycklar kommer inte att vara synliga längre vid den här tiden AFTER DELETE utlösaren anropas. (Det händer helt klart i en transaktion. Ingen av dessa detaljer spelar någon roll för andra transaktioner, som kommer att se alla eller inga effekter. Se manualen för mer om MVCC-modell och transaktionsisolering .)

Därför, om du vill inkludera värden från rader beroende på ett sådant sätt i din INSERT , se till att anropa den här utlösaren före dessa rader tas bort.

Du kanske måste göra denna utlösare BEFORE DELETE .

Eller så kan det innebära att du måste beställa dina triggers därefter, BEFORE triggers kommer före AFTER triggers, uppenbarligen. Och triggers på samma nivå exekveras i alfabetisk ordning .

Men så länge jag är superprecis här, kan jag också lägga till att ändringar har gjorts på raden (eller beroende rader) i andra BEFORE utlösare är också bara synliga om de kallas före den här.

Mitt råd att göra det till en AFTER triggern berodde på att den är mindre benägen för komplikationer och billigare om andra trigger kan avbryta (återställa) DELETE halvvägs genom operationen - så länge inget av ovanstående gäller.



  1. 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' misslyckades

  2. Hur man uppdaterar tabellen i oracle

  3. Skapa fysiska säkerhetskopior av dina MariaDB- eller MySQL-databaser

  4. Om RM-formatelementet i Oracle