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

Jak přimět PostgreSQL vložit řádek do tabulky při odstranění z jiné tabulky?

Napište spouštěcí funkci. Něco takového:

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;

A spouštěč ON DELETE . Takhle:

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

Klíčové prvky

  • Nejlepší je, aby to bylo spouštěč AFTER DELETE a FOR EACH ROW .

  • Chcete-li vrátit všechny sloupce ze staré tabulky, použijte syntaxi (OLD).* . Přečtěte si příručku o přístupu ke složeným typům . Případně OLD.* je také platná syntaxe, protože OLD je přidán do FROM klauzule implicitně. Pro VALUES výraz by musel být (OLD).* , ačkoli. Jako:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Můžete zahrnout hodnoty z jakékoli jiné tabulky, jak demonstruji. Ujistěte se, že získáte jeden řádek, nebo vytvoříte více položek.

  • Když se spouštěč spustí AFTER V případě události může funkce RETURN NULL .

O viditelnosti

V reakci na bdělý komentář @couling.

Zatímco cizí klíče lze prohlásit jako DEFERRED kód> , pouze odloží kontrolu integrity, nikoli samotné odstranění. Řádky, které jsou odstraněny v triggerech spuštěných před tím, který je k dispozici nebo od ON DELETE CASCADE cizí klíče již nebudou viditelné v době tohoto AFTER DELETE se nazývá spoušť. (Všechno se samozřejmě děje v jedné transakci. Na žádné z těchto podrobností nezáleží u jiných transakcí, které zaznamenají všechny nebo žádné účinky. Další informace o Model MVCC a izolace transakcí .)

Pokud tedy chcete do INSERT zahrnout hodnoty z řádků závislých tímto způsobem , nezapomeňte tento spouštěč zavolat před tyto řádky budou smazány.

Možná budete muset tento spouštěč nastavit BEFORE DELETE .

Nebo to může znamenat, že musíte spouštěče podle toho objednat BEFORE spouštěče jsou před AFTER spouště, samozřejmě. A spouštěče na stejné úrovni se spouštějí v abecedním pořadí .

Nicméně pokud jsem zde velmi přesný, mohu také dodat, že změny provedené v řádku (nebo závislých řádcích) v jiných BEFORE spouštěče jsou také viditelné pouze v případě, že jsou nazývány před tento.

Moje rada, aby to bylo AFTER trigger byl proto, že je méně náchylný ke komplikacím a levnější, pokud by jiný spouštěč mohl zrušit (vrátit zpět) DELETE v polovině operace – pokud neplatí nic z výše uvedeného.



  1. Přehled logické replikace v PostgreSQL

  2. Jak přidat dynamický sloupec do existující tabulky

  3. Chyba připojení k serveru SQL Server 2008 Na druhém konci kanálu není žádný proces

  4. Připojte se ke 3 stolům s Count