sql >> Base de Datos >  >> RDS >> PostgreSQL

El disparador de PostgreSQL no devuelve nada

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)