Twoje pytanie pozostawia pole do interpretacji. Rozumiem to, że chcesz RETURNING
klauzula INSERT
polecenie, aby zwrócić wartość klucza głównego wygenerowanego przez sekwencję.
Są inne sposoby, aby to osiągnąć. Jak przy użyciu nextval()
aby uzyskać następny id
z sekwencji wcześniej i wstaw wiersz z id
przeliterowane.
LUB currval()
/ lastval()
aby uzyskać ostatnio uzyskaną wartość dla sekwencji / dowolnej sekwencji w bieżącej sesji. Więcej w tej powiązanej odpowiedzi:
Następna wartość sekwencji w PostgreSQL?
Możesz również użyć RULE ... INSTEAD ..
w tym celu.
Ale, aby odpowiedzieć na Twoje pytanie – jeśli to jest w rzeczywistości Twoje pytanie:można to zrobić za pomocą dwóch wyzwalaczy . Jeden BEFORE
, jeden AFTER INSERT
.Oba są uruchamiane w jednej transakcji na definicję, więc fantomowy wiersz w pierwszej tabeli nigdy nie jest widoczny dla nikogo (z wyjątkiem wyzwalaczy).
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();
Zadzwoń w 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)