Sua pergunta deixa margem para interpretação. Pelo que entendi, você quer o
RETURNING
cláusula do INSERT
comando para retornar o valor da chave primária gerada por uma sequência. Existem outras maneiras de conseguir isso. Como usar
nextval()
para obter o próximo id
da sequência de antemão e insira a linha com o id
soletrado.OU
currval()
/ lastval()
para obter o valor obtido mais recentemente para uma sequência/qualquer sequência na sessão atual. Mais nesta resposta relacionada:Próximo valor do PostgreSQL das sequências?
Você também pode usar uma
RULE ... INSTEAD ..
para este fim. Mas, para responder à sua pergunta - se essa for, de fato, sua pergunta:isso pode ser feito usando dois gatilhos . Um
BEFORE
, um AFTER INSERT
.Ambos são disparados em uma transação por definição, então a linha fantasma em sua primeira tabela nunca é visível para ninguém (exceto os gatilhos). Demonstração:
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();
Chama no 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)