Ben*_*Jin 11 postgresql triggers plpgsql
我们有一个应用程序,它将根据用户请求从表中删除一行.我无法更改应用程序代码.但是,我想根据要删除的行的信息,使用来自其他几个表的信息将一行插入另一个表(有点像日志日志).
我如何在PostgreSQL中实现这一目标?
Erw*_*ter 14
写一个触发函数.像这样的东西:
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;
Run Code Online (Sandbox Code Playgroud)
并触发ON DELETE.像这样:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Run Code Online (Sandbox Code Playgroud)
最好使之成为触发AFTER DELETE和FOR EACH ROW.
要返回旧表中的所有列,请使用语法(OLD).*.请参阅有关访问复合类型的手册.或者OLD.*也是有效的语法,因为隐式地OLD添加到FROM子句中.但是,对于VALUES表达式,它必须是(OLD).*.喜欢:
INSERT INTO other_tbl
VALUES((OLD).*, some_variable)
Run Code Online (Sandbox Code Playgroud)您可以包含我演示的任何其他表中的值.只需确保获得一行,或者创建多个条目.
当触发器触发AFTER事件时,函数可以RETURN NULL.
回应@ couling的注意评论.
虽然外键可以声明为DEFERRED,但这只会推迟完整性检查,而不是删除本身.那些在一个手头之前触发器执行删除的行或由ON DELETE CASCADE外键将不可见任何更在这个时间AFTER DELETE触发器被调用.(这一切都发生在一个交易明显.这些细节没有关系的其他交易,这将看到的效果全或无的.请参阅手册,了解更多关于MVCC模型和事务隔离.)
因此,如果您希望在您的行中包含依赖于行的值,请INSERT确保在删除这些行之前调用此触发器.
你可能不得不做这个触发器BEFORE DELETE.
或者它可能意味着你必须相应地订购你的触发器,显然BEFORE触发器触发前AFTER.并且在同一级别的触发器按字母顺序执行.
但是,只要我在这里非常精确,我可能还会补充说,对其他BEFORE触发器中的行(或依赖行)所做的更改也只有在此之前调用它们时才可见.
我的建议,使其成为一个AFTER触发是因为它是不容易的并发症和便宜,如果其他触发可能会取消(回滚)的DELETE中途操作-只要没有上述适用.
| 归档时间: |
|
| 查看次数: |
13457 次 |
| 最近记录: |