PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да накарам PostgreSQL да вмъкне ред в таблица, когато бъде изтрит от друга таблица?

Напишете тригерна функция. Нещо подобно:

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;

И тригер ON DELETE . Като това:

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

Ключови елементи

  • Най-добре го направете тригер СЛЕД ИЗТРИВАНЕ и ЗА ВСЕКИ РЕД .

  • За да върнете всички колони от старата таблица, използвайте синтаксиса (OLD).* . Вижте ръководството за достъп до съставни типове . Като алтернатива OLD.* също е валиден синтаксис, защото OLD се добавя към FROM клауза имплицитно. За VALUES израз, той трябва да бъде (OLD).* , обаче. Като:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Можете да включите стойности от всяка друга таблица, както демонстрирам. Просто се уверете, че получавате един ред или създавате множество записи.

  • Тъй като тригерът задейства СЛЕД събитието, функцията може да ВРЪЩА NULL .

Относно видимостта

В отговор на внимателния коментар на @couling.

Докато външните ключове могат да бъдат декларирани като ОТЛОЖЕНИ , това ще отложи само проверката на целостта, но не и самото изтриване. Редове, които са изтрити в тригери, изпълнени преди текущия или от ON DELETE CASCADE външните ключове повече няма да се виждат по време на това СЛЕД ИЗТРИВАНЕ се извиква тригер. (Очевидно всичко се случва в една транзакция. Нито една от тези подробности няма значение за други транзакции, които ще видят всички или нито един от ефектите. Обърнете се към ръководството за повече относно MVCC модел и изолация на транзакция .)

Следователно, ако искате да включите стойности от редове, зависещи по такъв начин във вашия INSERT , не забравяйте да извикате този тригер преди тези редове се изтриват.

Може да се наложи да направите този тригер ПРЕДИ ИЗТРИВАНЕ .

Или може да означава, че трябва да подредите тригерите си по съответния начин, ПРЕДИ тригерите идват преди СЛЕД задейства, очевидно. И тригерите на същото ниво се изпълняват в азбучен ред .

Въпреки това, докато съм супер точен тук, мога също да добавя, че промените, направени в реда (или в зависимост от редовете) в други ПРЕДИ тригерите също се виждат само ако са извикани before този.

Моят съвет е да го направите СЛЕД задействането беше, защото е по-малко податливо на усложнения и по-евтино, ако друго задействане може да отмени (върни) DELETE по средата на операцията - стига нито едно от горните да не е приложимо.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да активирам разширението без акцент върху вече съществуващ модел

  2. Проверете цяла таблица за една стойност

  3. Динамична централна заявка с помощта на PostgreSQL 9.3

  4. SQL заявка, използваща клауза WHERE IN

  5. Генериране на последователност в ред