Вашият въпрос оставя място за тълкуване. Доколкото разбирам, вие искате 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)