如果在postgresql中创建/更新了一行,如何触发另一行记录的创建/更新

时间:2014-01-10 16:43:31

标签: postgresql

我正在接收外部记录csv,然后当我创建或更新postgresql中的条目时,我需要创建一个只有符号差异的镜像条目。这可以在程序级别完成,我很想知道是否可以使用触发器。 对于我能找到的例子,它们都以代码结束,     FOR EACH ROW EXECUTE PROCEDURE foo() 通常处理检查,使用NEW.additionalfield添加附加信息,或插入另一个表。如果我以这种方式使用触发器在同一个表中插入另一行,似乎触发器将再次触发并且创建变为递归。 有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

处理触发器时,经验法则是:

  1. 如果它根据某些业务规则或其他更改当前行(例如添加额外信息或处理计算字段),则它属于BEFORE触发器。< / p>

  2. 如果它对单独的表中的一行或多行有副作用,则它属于AFTER触发器。

  3. 如果它在任何表上运行完整性检查,没有其他内置约束(检查,唯一键,外键,排除等)可以处理,它属于CONSTRAINT [后]触发器。

  4. 如果它对相同表中的一个或多个其他行有副作用,您应该重新访问您的架构,代码流或两者。

  5. 关于最后一点,Postgres中确实存在变通方法,例如尝试获取锁或检查xmin与事务的xid,以避免在递归方案中陷入困境。最新版本另外引入了pg_trigger_depth()。但我仍然反对它。

    请注意,约束触发器可以创建为deferrable initially deferred。这会将约束触发器延迟到事务的最后,而不是在语句之​​后立即。

    您的问题和昵称暗示您想知道如何在复式簿记应用程序中自动平衡一组行。假设是这样,不要自动创建平衡条目。相反,开始一个事务,分别输入每一行,并且(对于每一行,最初推迟的延迟)约束触发器从那里拾取并且如果任何不平衡则拒绝整个批次。当你想要平衡超过两三条线时,以这种方式进行将避免一大堆头痛。

    另一种解读可能是您要创建审计跟踪。如果是,请创建其他审计表并使用after触发器填充它们。有多种方法可以创建和管理这些审计表。看看slowly changing dimensions。 (如果您对表的完整历史记录感兴趣,包括其关系历史记录,则Fwiw,类型为start_endtsrangetstzrange的类型6适用于审计表与其他审计表。)使用应用程序的“实时”表来保持快速,并在需要历史报告时使用审计表。