Dit spørgsmål giver plads til fortolkning. Som jeg forstår det, vil du have RETURNING
klausul af INSERT
kommando for at returnere værdien af den primære nøgle genereret af en sekvens.
Der er andre måder at opnå dette på. Som at bruge nextval()
for at få det næste id
fra sekvensen på forhånd, og indsæt rækken med id
stavet ud.
ELLER currval()
/ lastval()
for at få den senest opnåede værdi for en sekvens / enhver sekvens i den aktuelle session. Mere i dette relaterede svar:
PostgreSQL næste værdi af sekvenserne?
Du kan også bruge en RULE ... INSTEAD ..
til dette formål.
Men for at besvare dit spørgsmål - hvis det i virkeligheden er dit spørgsmål:det kan gøres ved at bruge to triggere . Én BEFORE
, en AFTER INSERT
.Begge udløses i én transaktion pr. definition, så fantomrækken i din første tabel er aldrig synlig for nogen (undtagen udløserne).
Demo:
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();
Kald 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)