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

删除回忆录丶 提交于 2019-12-04 01:13:37

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:

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?

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

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!