PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Il trigger di PostgreSQL non restituisce nulla

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)