INSERTAR…VOLVER..aparece vacío cuando ANTES del disparador cancela la declaración
-
21-12-2019 - |
Pregunta
Tengo un activador PostgreSQL antes de insertar al crear que básicamente redirige las inserciones a subtablas.Una vez que inserto el registro, quiero ABORTAR la solicitud para evitar datos duplicados (al no insertarlos en la tabla principal), por lo que estoy usando return NULL en el disparador.El problema es que necesito que me devuelvan el registro para poder obtener la identificación.Si devuelvo NULL, obtengo NULL.
El problema anterior se analiza en el siguiente enlace:El disparador de PostgreSQL no devuelve nada
Una de las respuestas dice insertar en la tabla principal (no devolviendo nulo sino nuevo) y usar el disparador DESPUÉS de insertar para eliminarlo de la tabla principal.Pero estoy viendo 1000 escrituras por segundo y esto puede ser un problema grave de rendimiento debido a las eliminaciones. ¿Hay alguna otra forma de hacer esto?
Para ser exactos, ¿hay alguna manera de devolver la identificación de una fila insertada sin insertarla en la tabla principal y eliminarla más tarde?
Solución
escribí la respuesta a la que te refieres.Como ya insinué por allí:
También podrías usar un
RULE ... INSTEAD ..
para este propósito.
RULE
Normas puede ser complicado.Prefiero usar disparadores siempre que sea posible. Asegúrate de leer un poco., antes de intentar esto:
CREATE OR REPLACE RULE tbl_ins AS
ON INSERT TO tbl
DO INSTEAD
INSERT INTO tbl2 (col1, col2, ...) -- just do mention columns where ...
VALUES (NEW.col1, NEW.col2, ...) -- ... you want to insert column defaults
RETURNING tbl2.*
Eso devolvería valores de tbl2
evitando al mismo tiempo filas fantasma. Sin embargo, por documentación en CREATE RULE
:
en una regla para
INSERT
,UPDATE
, oDELETE
en una vista, puede agregar unRETURNING
cláusula que emite las columnas de la vista.Esta cláusula se usará para calcular las salidas si la regla es activada por unINSERT RETURNING
,UPDATE RETURNING
, oDELETE RETURNING
comando respectivamente.Cuando la regla se activa mediante un comando sinRETURNING
, las normasRETURNING
cláusula será ignorada. La implementación actual permite solo incondicionalINSTEAD
reglas para contenerRETURNING
;
El énfasis en negrita es mío.
Ya que mencionas sub-tables
, Supongo que necesitarías condiciones para distribuir los insertos...
currval()
/ lastval()
Si opera con un gatillo FOR EACH ROW
puede obtener fácilmente valores apropiados de secuencias con currval()
/ lastval()
.La parte complicada es devolver esos valores desde una función de activación.Sólo puedo pensar en escribir en una tabla temporal.Necesita pensar un poco cuándo crear y cuándo abandonarlo...
Yo probablemente repensar todo el enfoque y redirigir los datos a múltiples INSERT
declaraciones a tablas de destino reales ...