PostgreSQL's rules and nextval()/serial problem (very PostgreSQL-specific)

前端 未结 2 1176
暖寄归人
暖寄归人 2021-02-20 08:58

When I use a rewrite rule that splits an insert into one table into inserts to two other tables where one of the inserted values has as default nextval(\'some_sequence\') with t

相关标签:
2条回答
  • 2021-02-20 09:47

    Rules will do that for you - they rewrite the query before it's executed.

    As long as you have an actual table for the base (Children1), I think you'll be able to accomplish the same thing with a TRIGGER instead of a RULE.

    0 讨论(0)
  • 2021-02-20 09:49

    From the docs http://www.postgresql.org/docs/8.4/static/rules.html

    It (The Rule system) modifies queries to take rules into consideration, and then passes the modified query to the query planner for planning and execution

    so it first rewrites the queries without executing anything.

    you can make it work when you do not insert multipe records at once:

    create or replace rule ct_i_children1 as
      on insert to Children1
      do instead (
        insert into Parents(id, attribute1, type)
          values(nextval('parents_id_seq'), new.attribute1, 'Child1');
        insert into Partial_Children1(id, attribute2, type)
          values(currval('parents_id_seq'), new.attribute2, 'Child1');
      );
    

    Then you can do:

    insert into Children1 (attribute1, attribute2) values ('a1', 'a2');
    insert into Children1 (attribute1, attribute2) values ('b1', 'b2');
    

    but not

    insert into Children1 (attribute1, attribute2)
      values ('a1', 'a2'),
             ('b1', 'b2');
    

    So you really should not use the rules system with tricky currval() calls.

    Additionally take a look at the comments on these pages:

    • http://www.postgresql.org/docs/8.2/interactive/rules-update.html
    • http://archives.postgresql.org/pgsql-sql/2004-10/msg00195.php
    • http://archives.postgresql.org/pgsql-general/2009-06/msg00278.php

    Another tip: the support at the postgresql mailing list is as excellent as the database engine itself!

    And by the way: do your know that postgresql has support for inheritance out-of-the-box?

    • http://www.postgresql.org/docs/8.4/interactive/ddl-inherit.html

    Summary: you should use triggers or avoid multiple row inserts!

    0 讨论(0)
提交回复
热议问题