要在第二个表中自动添加列以通过唯一索引将其绑定到第一个表,我有一个如下规则:
CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid);
如果 user.userid 是整数,则此方法可以正常工作。但是,如果它是序列(例如,键入串行或 bigserial ),则插入表 lastlogin 的内容是下一个序列ID。所以这个命令:
INSERT INTO user (username) VALUES ('john');
会将列[1,'john',...]插入用户,但将列[2,...]插入 lastlogin 。以下2个变通方法有效,但第二个变量消耗了两倍的序列号,因为序列仍然是自动递增的:
CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (lastval());
CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid-1);
不幸的是,如果我插入多行,解决方法不起作用:
INSERT INTO user (username) VALUES ('john'), ('mary');
第一个解决方法将使用相同的ID,第二个解决方法是所有类型的搞砸。
是否可以通过postgresql规则执行此操作,还是应该自己第二次插入 lastlogin 或使用行触发器?实际上,我认为当我访问 NEW.userid 时,行触发器也会自动递增序列。
答案 0 :(得分:6)
完全忘记规则。他们糟糕。
触发器对你来说更好。在99%的情况下,有人认为他需要一个规则。试试这个:
create table users (
userid serial primary key,
username text
);
create table lastlogin (
userid int primary key references users(userid),
lastlogin_time timestamp with time zone
);
create or replace function lastlogin_create_id() returns trigger as $$
begin
insert into lastlogin (userid) values (NEW.userid);
return NEW;
end;
$$
language plpgsql volatile;
create trigger lastlogin_create_id
after insert on users for each row execute procedure lastlogin_create_id();
然后:
insert into users (username) values ('foo'),('bar');
select * from users;
userid | username --------+---------- 1 | foo 2 | bar (2 rows)
select * from lastlogin;
userid | lastlogin_time --------+---------------- 1 | 2 | (2 rows)