如何在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;
和一个触发器删除.喜欢这个:
CREATE TRIGGER delaft AFTER DELETE ON tbl FOR EACH ROW EXECUTE PROCEDURE trg_backup_row();
关键要素
最好让它成为trigger AFTER DELETE
and FOR EACH ROW
.
>要从旧表中返回所有列,请使用语法(OLD).*.请参阅手册关于accessing composite types.或者,OLD.*也是有效的语法,因为OLD被隐式添加到FROM子句.对于一个VALUES表达式,它必须是(OLD).*.喜欢:
INSERT INTO other_tbl VALUES((OLD).*,some_variable)
>您可以包括任何其他表格中的值,如我所示.只需确保获得单个行,或者创建多个条目.
>触发器在事件发生后触发,函数可以返回NULL.
关于知名度
回应@ couling的注意的评论.
虽然外键可以是declared as DEFERRED
,但这只会延迟完整性检查,而不是删除本身.在手头或ON DELETE CASCADE外键之前执行的触发器中删除的行在调用此AFTER DELETE触发器之后将不再可见. (这一切都发生在一个交易中,这些细节对于其他交易都不重要,这将显示所有或没有任何效果.有关MVCC model and transaction isolation的更多信息,请参阅手册)
因此,如果要在INSERT中包含来自行的值,请确保在删除这些行之前调用此触发器.
您可能必须在删除之前使此触发器.
或者这可能意味着您必须相应地订购您的触发器,BEFORE触发器来自AFTER触发器之前,显然.同级别的触发器在alphabetical order执行.
但是,只要我在这里非常精确,我还可以补充说,在其他BEFORE触发器中对行(或依赖行)所做的更改也只有在这个触发器之前被调用时才可见.
我建议将其做为AFTER触发器是因为如果其他触发器可能会通过操作取消(回滚)DELETE一半,那么它不太容易出现并发症,而且更便宜 – 只要以上不适用.