Ваш вопрос оставляет место для толкования. Насколько я понимаю, вы хотите, чтобы предложение RETURNING
команды INSERT
возвращало значение первичного ключа, сгенерированного последовательностью.
Есть и другие способы достижения этого. Например, используя nextval()
, чтобы заранее получить следующий id
из последовательности и вставить строку с прописной id
.
ИЛИ currval()
/ lastval()
, чтобы получить последнее полученное значение для последовательности / любой последовательности в текущем сеансе. Больше в этом связанном ответе:
PostgreSQL следующее значение последовательностей?
Вы также можете использовать RULE ... INSTEAD ..
для этой цели.
Но, чтобы ответить на ваш вопрос - если это на самом деле ваш вопрос: это можно сделать, используя два триггера . Один BEFORE
, один AFTER INSERT
.
Оба запускаются в одной транзакции для каждого определения, поэтому фантомная строка в вашей первой таблице никогда не видна никому (кроме триггеров).
Демо-версия:
CREATE TABLE x (
id serial PRIMARY KEY -- note the serial col.
,name text
);
CREATE TABLE y (
id integer PRIMARY KEY
,name text
);
CREATE OR REPLACE FUNCTION trg_x_insbef()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO y SELECT (NEW).*; -- write to other table
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER insbef
BEFORE INSERT ON x
FOR EACH ROW EXECUTE PROCEDURE trg_x_insbef();
CREATE OR REPLACE FUNCTION trg_x_insaft()
RETURNS trigger AS
$func$
BEGIN
DELETE FROM x WHERE id = NEW.id; -- delete row again.
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER insaft
AFTER INSERT ON x
FOR EACH ROW EXECUTE PROCEDURE trg_x_insaft();
Позвоните в psql:
db=# INSERT INTO x (name) values('phantom') RETURNING id;
id
----
1
(1 row)
INSERT 0 1
db=# SELECT * FROM x;
id | name
----+------
(0 rows)
db=# SELECT * FROM y;
id | name
----+---------
1 | phantom
(1 row)