Для автоматического добавления столбца во второй таблице для связи его с первой таблицей через уникальный индекс у меня есть правило такой следующим образом:
CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid);
Это хорошо работает, если user.userid является целым числом. Однако, если это - последовательность (например, введите последовательный или bigserial), что вставляется в таблицу lastlogin, следующий идентификатор последовательности. Так эта команда:
INSERT INTO user (username) VALUES ('john');
вставил бы столбец [1, 'Джон'...] в пользователя, но столбец [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');
Первое обходное решение использовало бы тот же идентификатор, и второе обходное решение является всем видом провала.
Действительно ли возможно сделать это через правила postgresql, или я должен просто сделать 2-ю вставку в lastlogin сам или использовать триггер строки? На самом деле я думаю, что триггер строки был бы также автоинкремент последовательность, когда я получаю доступ к NEW.userid.
Forget rules altogether. Они плохие.
Триггеры намного лучше для вас. И в 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)