【问题标题】:INSERT ...RETURNING .. comes up empty when BEFORE trigger cancels statement当 BEFORE 触发器取消语句时,INSERT ...RETURNING .. 为空
【发布时间】:2014-06-04 19:43:01
【问题描述】:

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

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

其中一个答案是插入到父表中(通过不返回 null 而是返回新的)并使用 AFTER insert 触发器将其从父表中删除。但我正在查看每秒 1000 次写入,由于删除,这可能是一个严重的性能问题。有没有其他方法可以做到这一点?

确切地说,有一种方法可以返回插入行的 id,而无需插入父表并稍后将其删除。

【问题讨论】:

    标签: database postgresql triggers column-defaults


    【解决方案1】:

    我写了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 发出视图列的子句。该条款将 如果规则被触发,则用于计算输出 分别是INSERT RETURNINGUPDATE RETURNINGDELETE RETURNING 命令。 当规则由不带RETURNING 的命令触发时,规则的 RETURNING 子句将被忽略。 当前的实现允许 只有无条件的INSTEAD 规则才能包含RETURNING

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

    currval() / lastval()

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

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

    【讨论】:

    • 感谢您的回复.. 我害怕使用规则,因为它不支持 COPY,我们确实会备份和恢复数据库,但由于规则不是由 COPY 命令激活,因此规则变得很困难.一个快速的问题 currval() 返回插入的 id,但如果我在单个插入语句中插入多行,它会返回批量插入的所有 id 吗?谢谢
    • @user3654243:我添加了更多内容来解决这个问题。
    • 谢谢.. 可能我会选择“将数据重定向到多个 INSERT 语句到实际目标表...”
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    相关资源
    最近更新 更多