Escreva uma função de gatilho. Algo assim:
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;
E um gatilho
ON DELETE
. Assim:CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Elementos-chave
-
Melhor torná-lo um triggerAFTER DELETE
ePARA CADA LINHA
.
-
Para retornar todas as colunas da tabela antiga, use a sintaxe(OLD).*
. Consulte o manual sobre como acessar tipos compostos . Como alternativaOLD.*
também é uma sintaxe válida, porqueOLD
é adicionado aoFROM
cláusula implicitamente. Para umVALUES
expressão teria que ser(OLD).*
, no entanto. Curti:
INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Você pode incluir valores de qualquer outra tabela como demonstro. Apenas certifique-se de obter uma única linha ou crie várias entradas.
-
À medida que o gatilho disparaAFTER
o evento, a função podeRETURN NULL
.
Sobre visibilidade
Em resposta ao comentário atento de @couling.
Enquanto as chaves estrangeiras podem ser declaradas como
DEFERRED
, isso apenas adiará a verificação de integridade, não a exclusão em si. Linhas que são excluídas em gatilhos executados antes do que está em mãos ou por ON DELETE CASCADE
chaves estrangeiras não serão mais visíveis no momento em que APÓS EXCLUIR
gatilho é chamado. (Tudo acontece em uma transação, obviamente. Nenhum desses detalhes importa para outras transações, que verão todos ou nenhum dos efeitos. Consulte o manual para saber mais sobre o Modelo MVCC e isolamento de transações
.) Portanto, se você deseja incluir valores de linhas dependendo dessa maneira em seu
INSERT
, certifique-se de chamar esse acionador antes essas linhas são excluídas. Você pode ter que fazer este gatilho
BEFORE DELETE
. Ou pode significar que você precisa ordenar seus gatilhos de acordo,
ANTES
os gatilhos vêm antes de AFTER
gatilhos, obviamente. E os gatilhos no mesmo nível são executados em ordem alfabética
. No entanto, desde que eu seja super preciso aqui, também posso adicionar as alterações feitas na linha (ou linhas dependentes) em outro
ANTES
os gatilhos também só são visíveis se forem chamados antes Este. Meu conselho para torná-lo um
DEPOIS
gatilho foi porque é menos propenso a complicações e mais barato se outro gatilho puder cancelar (reverter) o DELETE
no meio da operação - desde que nenhuma das opções acima se aplique.