微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当从另一个表中删除时,如何使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;

一个触发器删除.喜欢这个:

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一半,那么它不太容易出现并发症,而且更便宜 – 只要以上不适用.

原文地址:https://www.jb51.cc/postgresql/191703.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐