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

Hvordan får man PostgreSQL til at indsætte en række i en tabel, når den slettes fra en anden tabel?

Skriv en triggerfunktion. Noget som dette:

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;

Og en trigger ON SLET . Sådan:

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

Nøgleelementer

  • Gør det bedst til en trigger EFTER SLETNING og FOR HVER RÆKKE .

  • For at returnere alle kolonner fra den gamle tabel skal du bruge syntaksen (OLD).* . Se manualen om adgang til sammensatte typer . Alternativt OLD.* er også gyldig syntaks, fordi OLD er føjet til FROM klausul implicit. For en VALUES udtryk det skulle være (GAMMEL).* , selvom. Ligesom:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Du kan inkludere værdier fra enhver anden tabel, som jeg viser. Bare sørg for at få en enkelt række, ellers opretter du flere poster.

  • Når udløseren udløses AFTER begivenheden, kan funktionen RETURN NULL .

Om synlighed

Som svar på @coulings opmærksomme kommentar.

Mens fremmednøgler kan erklæres som UDSKITTET , vil dette kun udskyde integritetskontrollen, ikke selve sletningen. Rækker, der er slettet i triggere, der udføres før den ved hånden eller ved PÅ SLET CASCADE fremmednøgler vil ikke længere være synlige på det tidspunkt denne EFTER SLETT trigger kaldes. (Det hele sker naturligvis i én transaktion. Ingen af ​​disse detaljer betyder noget for andre transaktioner, som vil se alle eller ingen af ​​virkningerne. Se manualen for mere om MVCC-model og transaktionsisolering .)

Derfor, hvis du ønsker at inkludere værdier fra rækker afhængigt på en sådan måde i din INSERT , sørg for at kalde denne trigger før disse rækker bliver slettet.

Du skal muligvis lave denne trigger FØR SLETT .

Eller det kan betyde, at du skal bestille dine triggere i overensstemmelse hermed, FØR triggere kommer før AFTER udløser, selvfølgelig. Og triggere på samme niveau udføres i alfabetisk rækkefølge .

Men så længe jeg er super præcis her, kan jeg også tilføje, at ændringer foretaget i rækken (eller afhængige rækker) i andre BEFORE udløsere er også kun synlige, hvis de kaldes før denne.

Mit råd til at gøre det til en AFTER trigger var, fordi den er mindre tilbøjelig til komplikationer og billigere, hvis en anden trigger kan annullere (rulle tilbage) DELETE halvvejs gennem operationen - så længe intet af ovenstående gælder.



  1. Hvordan kan jeg validere data før indsættelse/opdatering med SQL Server?

  2. Er det muligt at patch indlæse SQL-sætninger fra en fil ved hjælp af clojure.java.jdbc?

  3. PDO hente / henteAlle

  4. Hvordan afrundes et gennemsnit til 2 decimaler i PostgreSQL?