La tua domanda lascia spazio all'interpretazione. Per come la intendo io, vuoi il RETURNING
clausola del INSERT
comando per restituire il valore della chiave primaria generata da una sequenza.
Ci sono altri modi per raggiungere questo obiettivo. Come usare nextval()
per ottenere il prossimo id
dalla sequenza in anticipo e inserire la riga con il id
esplicitato.
OPPURE currval()
/ lastval()
per ottenere il valore ottenuto più di recente per una sequenza/qualsiasi sequenza nella sessione corrente. Altro in questa risposta correlata:
PostgreSQL valore successivo delle sequenze?
Potresti anche usare una RULE ... INSTEAD ..
a questo scopo.
Ma, per rispondere alla tua domanda - se questa è, in effetti, la tua domanda:può essere fatto utilizzando due trigger . Un BEFORE
, un AFTER INSERT
.Entrambi vengono attivati in una transazione per definizione, quindi la riga fantasma nella prima tabella non è mai visibile a nessuno (tranne i trigger).
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();
Chiama in 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)