具有序列字段、规则和错误当前值/序列的 PostgreSQL
PostgreSQL with serial fields , rule and wrong currval / sequence
通常使用 PotsgreSQL 基于 CRUD 事件将记录插入日志 table 需要(至少)一个触发器和一个触发器函数。我试图使用 Postgres RULES 使其更容易。它几乎可以工作,但以下情况除外:
create table mydata ( somedata char(4) , id1 bigserial );
create table mylog ( logid bigint , op char(1), id2 bigserial );
create rule mydata_ilog as on insert to mydata do insert into mylog( logid , op ) values ( new.id1 ,'i' );
insert into mydata( somedata ) values ('0001');
主 table 和日志 table 有一个序列字段,我希望 - 在将一条记录插入 mydata
之后 - 在 mydata 中有一条记录 id1=1
,以及mylog
中的一条记录,其中logid=1
(作为mydata记录的id),以及id2=1
...在mydata
,id1=1
,对...是mylog
,id2
是1,对...但是在mylog
,logid
字段是2
,数据库序列创建增加 id1
序列字段是 2
...
select currval('mydata_id1_seq'); -- return 2 ?!
select last_value from mydata_id1_seq; -- return 2 ?!
select id1 from mydata -- return 1 ok
select id2 from mydata -- return 1 ok
select logid from mylog -- return 2 ?!
我已经用触发器和触发器函数解决了这个问题,效果很好。但是,PostgreSQL 这样做有什么理由吗?!
查看执行计划:
EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO mydata (somedata) VALUES ('0001');
QUERY PLAN
------------------------------------------------------------------------------------------------------------
Insert on myschema.mydata
-> Result
Output: '0001'::character(4), nextval('mydata_id1_seq'::regclass)
Insert on myschema.mylog
-> Result
Output: nextval('mydata_id1_seq'::regclass), 'i'::character(1), nextval('mylog_id2_seq'::regclass)
(7 rows)
规则重写查询,使用与 mydata.id
相同的表达式用于第二个语句,因此您在两个语句中都有 nextval
调用。
数据修改查询的规则很难搞定,你就踏入了一个典型的陷阱。使用触发器。
通常使用 PotsgreSQL 基于 CRUD 事件将记录插入日志 table 需要(至少)一个触发器和一个触发器函数。我试图使用 Postgres RULES 使其更容易。它几乎可以工作,但以下情况除外:
create table mydata ( somedata char(4) , id1 bigserial );
create table mylog ( logid bigint , op char(1), id2 bigserial );
create rule mydata_ilog as on insert to mydata do insert into mylog( logid , op ) values ( new.id1 ,'i' );
insert into mydata( somedata ) values ('0001');
主 table 和日志 table 有一个序列字段,我希望 - 在将一条记录插入 mydata
之后 - 在 mydata 中有一条记录 id1=1
,以及mylog
中的一条记录,其中logid=1
(作为mydata记录的id),以及id2=1
...在mydata
,id1=1
,对...是mylog
,id2
是1,对...但是在mylog
,logid
字段是2
,数据库序列创建增加 id1
序列字段是 2
...
select currval('mydata_id1_seq'); -- return 2 ?!
select last_value from mydata_id1_seq; -- return 2 ?!
select id1 from mydata -- return 1 ok
select id2 from mydata -- return 1 ok
select logid from mylog -- return 2 ?!
我已经用触发器和触发器函数解决了这个问题,效果很好。但是,PostgreSQL 这样做有什么理由吗?!
查看执行计划:
EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO mydata (somedata) VALUES ('0001');
QUERY PLAN
------------------------------------------------------------------------------------------------------------
Insert on myschema.mydata
-> Result
Output: '0001'::character(4), nextval('mydata_id1_seq'::regclass)
Insert on myschema.mylog
-> Result
Output: nextval('mydata_id1_seq'::regclass), 'i'::character(1), nextval('mylog_id2_seq'::regclass)
(7 rows)
规则重写查询,使用与 mydata.id
相同的表达式用于第二个语句,因此您在两个语句中都有 nextval
调用。
数据修改查询的规则很难搞定,你就踏入了一个典型的陷阱。使用触发器。