当BEFORE触发器取消语句时,INSERT ... RETURNING ..变为空

时间:2014-06-04 19:43:02

标签: database postgresql triggers column-defaults

我在创建插入触发器之前有一个PostgreSQL基本上将插入重定向到子表。一旦我插入记录,我想中止请求,以避免重复数据(通过不插入父表)所以我在触发器中使用返回NULL。问题是我需要返回记录,以便我可以获取ID。如果我返回NULL,我得到NULL。

以下链接讨论了上述问题: PostgreSQL trigger not returning anything

其中一个答案是插入父表(通过不返回null但返回new)并使用AFTER插入触发器将其从父表中删除。但是我每秒看1000次写入,由于删除,这可能是性能上的一个严重问题。还有其他方法吗?

确切地说,有一种方法可以返回插入行的id而不插入父表并在以后删除它。

1 个答案:

答案 0 :(得分:0)

我写了the answer you are referring to。正如我已在那里暗示的那样:

  

您也可以使用RULE ... INSTEAD ..来实现此目的。

RULE

规则可能会非常棘手。我宁愿在可能的情况下使用触发器。 Be sure to read a bit,在您尝试之前:

CREATE OR REPLACE RULE tbl_ins AS
ON INSERT TO tbl
DO INSTEAD
INSERT INTO tbl2 (col1, col2, ...)  -- just do mention columns where ...
VALUES (NEW.col1, NEW.col2, ...)    -- ... you want to insert column defaults
RETURNING tbl2.*

这将从tbl2返回值,同时避免幻像行。 然而per documentation on CREATE RULE

  

在视图中INSERTUPDATEDELETE的规则中,您可以添加   发出视图列的RETURNING子句。这个条款将是   如果规则由a触发,则用于计算输出   分别是INSERT RETURNINGUPDATE RETURNINGDELETE RETURNING命令。   当规则由没有RETURNING的命令触发时,规则即可   RETURNING子句将被忽略。 目前的实施允许   只有无条件INSTEAD规则才能包含RETURNING;

大胆强调我的 既然你提到sub-tables,我认为你需要条件来分发插入内容......

currval() / lastval()

如果您使用触发器FOR EACH ROW进行操作,则可以轻松地从currval() / lastval()的序列中获取适当的值。棘手的部分是从触发函数返回这些值。我只能想到写一张临时表。需要一些思考何时创建以及何时删除那个...

我可能重新考虑整个方法并将数据重定向到多个INSERT语句到实际目标表...