INSERIR…RETORNANDO..aparece vazio quando o gatilho BEFORE cancela a instrução
-
21-12-2019 - |
Pergunta
Eu tenho um gatilho PostgreSQL antes de inserir na criação que basicamente redireciona as inserções para subtabelas.Depois de inserir o registro, quero ABORT a solicitação para evitar dados duplicados (não inserindo na tabela pai), por isso estou usando return NULL no gatilho.O problema é que preciso que o registro seja devolvido para poder pegar o ID.Se eu retornar NULL, recebo NULL.
O problema acima é discutido no link abaixo:O gatilho do PostgreSQL não retorna nada
Uma das respostas diz para inserir na tabela pai (não retornando nulo, mas retornando novo) e usar o gatilho AFTER insert para excluí-lo da tabela pai.Mas estou observando 1.000 gravações por segundo e isso pode ser um problema sério de desempenho por causa das exclusões. Existe alguma outra maneira de fazer isso?
Para ser exato, existe uma maneira de retornar o ID de uma linha inserida sem inserir na tabela pai e excluí-la posteriormente.
Solução
escrevi a resposta a que você está se referindo.Como já indiquei lá:
Você também pode usar um
RULE ... INSTEAD ..
para este propósito.
RULE
Regras pode ser complicado.Prefiro usar gatilhos sempre que possível. Não deixe de ler um pouco, antes de tentar isso:
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.*
Isso retornaria valores de tbl2
evitando linhas fantasmas. No entanto, por documentação em CREATE RULE
:
Em uma regra para
INSERT
,UPDATE
, ouDELETE
em uma visualização, você pode adicionar umRETURNING
cláusula que emite as colunas da visualização.Esta cláusula será usada para calcular as saídas se a regra for desencadeada por umINSERT RETURNING
,UPDATE RETURNING
, ouDELETE RETURNING
comando respectivamente.Quando a regra é acionada por um comando semRETURNING
, as regrasRETURNING
cláusula será ignorada. A implementação atual permite apenas incondicionalINSTEAD
regras para conterRETURNING
;
Ousada ênfase minha.
Já que você mencionou sub-tables
, presumo que você precisaria de condições para distribuir os inserts...
currval()
/ lastval()
Se você operar com um gatilho FOR EACH ROW
você pode facilmente buscar valores apropriados de sequências com currval()
/ lastval()
.A parte complicada é retornar esses valores de uma função de gatilho.Só consigo pensar em escrever para uma tabela temporária.É preciso pensar um pouco quando criar e quando abandonar esse ...
eu provavelmente iria repensar toda a abordagem e redirecionar os dados para vários INSERT
instruções para tabelas de destino reais...