Su pregunta deja espacio para la interpretación. Según tengo entendido, quieres el RETURNING
cláusula del INSERT
comando para devolver el valor de la clave principal generada por una secuencia.
Hay otras formas de lograr esto. Como usar nextval()
para obtener el siguiente id
de la secuencia de antemano e inserte la fila con el id
escrito.
O currval()
/ lastval()
para obtener el valor obtenido más recientemente para una secuencia/cualquier secuencia en la sesión actual. Más en esta respuesta relacionada:
PostgreSQL siguiente valor de las secuencias?
También podrías usar una RULE ... INSTEAD ..
para este propósito.
Pero, para responder a su pregunta, si esa es, de hecho, su pregunta:se puede hacer usando dos activadores . Uno BEFORE
, uno AFTER INSERT
Ambos se activan en una transacción por definición, por lo que la fila fantasma en su primera tabla nunca es visible para nadie (excepto los disparadores).
Demostración:
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();
Llamar en 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)