Postgresql:检测哪个外键触发了;在删除“之前”之前;触发
假设Postgresql:检测哪个外键触发了;在删除“之前”之前;触发,postgresql,Postgresql,假设T是一个包含两列的表:a和b,这两列分别引用表a和b。此类引用属于“删除级联”类型,因此如果删除了a或B中的一行,则与原始引用匹配的T中的行也将被删除 现在,我想在T上设置一个触发器“在删除行之前打开”:有没有办法检测是哪个引用触发了T中的行删除?换句话说:我能知道触发器是从A还是从B级联触发的吗 多谢各位 编辑 好的,我已经简化了这个问题。我有以下表格: 用户: id:整数序列主键 名称:字符变化(128) 验证链: id:整数序列主键 名称:字符变化(128) 验证链链接: 链
T
是一个包含两列的表:a
和b
,这两列分别引用表a
和b
。此类引用属于“删除级联”类型,因此如果删除了a
或B
中的一行,则与原始引用匹配的T
中的行也将被删除
现在,我想在T
上设置一个触发器“在删除行之前打开”:有没有办法检测是哪个引用触发了T
中的行删除?换句话说:我能知道触发器是从A
还是从B
级联触发的吗
多谢各位
编辑
好的,我已经简化了这个问题。我有以下表格:
用户:
- id:整数序列主键
- 名称:字符变化(128)
- id:整数序列主键
- 名称:字符变化(128)
- 链:删除级联上的整数外键validatorchains.id
- user:delete cascade上的整数外键users.id
- 下一步:删除集null上的整数外键users.id
- prev:删除集null时的整数外键users.id
validatorchainslinks
上我的“删除前打开”触发器的代码是:
BEGIN
UPDATE validatorchainslinks SET next = OLD.next WHERE next = OLD.user;
UPDATE validatorchainslinks SET prev = OLD.prev WHERE prev = OLD.user;
RETURN OLD;
END;
因此,目的是创建一个用户链接列表,以验证某种操作。为了验证操作,链中的所有用户都必须同意。当用户被删除时,在维护链表时会出现问题。上面的触发代码成功地重新链接了链的元素。但是,如果通过删除validatorchains
中的一行触发删除,会发生什么情况?我不希望触发器执行更新操作,但是跳过它,让系统删除引用相应验证程序链的所有行
希望这能有所帮助。您只需稍加修改就可以做到这一点 由于PG在级联的
DELETE
(在validatorchainslinks
中)触发的触发函数中未向您提供任何相关信息,因此您应该在删除外部记录(在用户
或validatorchains
中)之前的某个位置记录此信息。因此,您可以在DELETE之前编写一个触发器,用一个值更新validatorchainslinks
中的所有记录,然后在后一个表的触发器函数中检查该值。当然,这需要向表中添加一个字段
或者,您可以创建一个单独的表,列出即将删除的表中的记录,然后任何触发器函数都可以查看该信息。在删除前触发器中写入该表,并在删除后触发器中删除同一表上的记录。如果在多个表之间发生相同的模式(级联删除),这将是更优雅的解决方案
级联删除发生在单个事务中,因此您应该受到保护,不受竞争条件的影响。这是解决更大问题的一个步骤吗?如果我们知道总体目标是什么,我们可能会做得更好-您是否试图实施更高级别的完整性约束?好吧,更大的问题非常复杂,难以描述,我已经找到了解决它的替代方案。然而,我遇到了这种情况,我想知道是否有办法知道是什么约束或列触发了删除。理论上,如果使用AFTER
触发器,您可以查询引用的表以检查引用的行是否仍然存在。但是没有,在触发之前没有任何直接的。也许值得描述更大的问题。我更新了这个问题,以便大致了解我在寻找什么。感谢您的回复。您是否出于其他原因需要next
和prev
,和/或是否检查了它们的一致性?为什么你不能有一个序列号来表示每个链中用户的顺序?虽然我找到了解决问题的方法,而不需要我最初提出的问题,但这是一个非常有趣的方法。我将把它作为书签,以备将来可能的应用。非常感谢。