Usuário com melhor resposta
Trigger com tabelas delete cascade

Pergunta
-
Senhores,
Alguém poderia me responder como resolver a seguinte situação:
Tenho uma tabela PAI e outro FiLHO, onde os registros da tabela FILHO é deletado quando o registro da tabela PAI é excluido (delete cascade na tabela PAI). Existe uma trigger (for delete) na tabela FILHO que executa algumas atualizações em outras tabelas. O problema é que ao usar o recurso INNER JOIN com a tabela PAI na trigger e se tratando de exclusão de registro, o INNER JOIN não encontra o registro na tabela PAI. O mais estranho é que, sendo o evento delete cascade executado primeiro, porquê na trigger da tabela FILHO não encontra o registro no PAI, já que teoricamente seria apagado após os filhos serem apagado.
Respostas
-
Ola Emerson
Pelo que entendi, sua intenção é pegar os registros excluidos e inserir em uma outra tabela.
acredito que a clausula output poderá te ajudar e com melhor perfomance em relação ao trigger.
http://msdn.microsoft.com/pt-br/library/ms177564.aspx
USE tempdb; GO CREATE TABLE dbo.table1 ( id INT, employee VARCHAR(32) ); GO INSERT INTO dbo.table1 VALUES (1, 'Fred') ,(2, 'Tom') ,(3, 'Sally') ,(4, 'Alice'); GO DECLARE @MyTableVar TABLE ( id INT, employee VARCHAR(32) ); PRINT 'table1, before delete' SELECT * FROM dbo.table1; DELETE FROM dbo.table1 OUTPUT DELETED.* INTO @MyTableVar WHERE id = 4 OR id = 2; PRINT 'table1, after delete' SELECT * FROM dbo.table1; PRINT '@MyTableVar, after delete' SELECT * FROM @MyTableVar; DROP TABLE dbo.table1;
Att.
Marcelo Fernandes
MCP, MCDBA, MCSA, MCTS, MCITP, MCT.
Se útil, classifique!!!
Me siga no twitter: @marcelodba- Sugerido como Resposta Junior Galvão - MVPMVP quinta-feira, 15 de janeiro de 2015 17:49
- Marcado como Resposta Ricardo Barbosa Cortes sexta-feira, 16 de janeiro de 2015 13:15
Todas as Respostas
-
Emerson,
Deixe-me ver se entendi direito. Em algum momento dentro da trigger você precisa fazer um join com a tabela PAI e não consegue porque a constraint já foi disparada quando do delete do registro PAI, é isso?
Tente ver se você pode utilizar a tabela virtual INSERTED ou DELETED, que pode ser mais adequado no seu caso...
Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008
-
Emerson.
Veja a seguinte estrutura:
registro PAI apagado -- trigger disparado para apagar registro FILHO (fim do alcance do trigger)
registro FILHO apagado pelo trigger -- dispara outro trigger que não tem comunicação com o primeiro (neste momento o registro PAI já não existe mais).
O que tu tens que fazer é juntar estes dois trigger, em um só. Ai sim, tu vai ter a informação DELETED.XXX do PAI, para usar no INNER.
-
Exatamente. Estou usando na trigger do FILHO o DELETED. Só que o inner join com a tabela PAI não encontra o registo. Veja exemplo abaixo.
ALTER TRIGGER [dbo].[trg_estorna_ocorrencia_estoque]
ON [dbo].[tb_mvto_compra_item]
FOR DELETE AS
BEGININSERT INTO dbo.tb_mvto_estoque
(emvto_data)
SELECT c.cmp_dt_entrada
FROM DELETED INNER JOIN dbo.tb_mvto_compra c ON DELETED.cmp_id = c.cmp_id
END
-
-
-
-
O problema é que por estar usando o delete cascade no PAI, quando for tratar o FILHO na trigger do PAI, os FILHOS não existiram mais. A propósito, existe como fazer referência na trigger do FILHO na área do deleted do PAI? Caso não exista, terei que tratar a exclusão dos FILHOS na trigger do PAI, retirando o recurso de deleted cascade da tabela PAI. Gostaria de saber se também se é comum não usar deleted cascade quando se usa trigger com deleted?
- Editado Emerson Hebert quarta-feira, 14 de janeiro de 2015 20:05
-
Boa tarde,
Emerson, não fiz nenhum teste, mas acho que você talvez consiga fazer essa operação com uma instead of trigger na tabela pai, pois ela é acionada antes de as linhas serem excluidas.
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Editado gapimex quarta-feira, 14 de janeiro de 2015 20:15
-
Ola Emerson
Pelo que entendi, sua intenção é pegar os registros excluidos e inserir em uma outra tabela.
acredito que a clausula output poderá te ajudar e com melhor perfomance em relação ao trigger.
http://msdn.microsoft.com/pt-br/library/ms177564.aspx
USE tempdb; GO CREATE TABLE dbo.table1 ( id INT, employee VARCHAR(32) ); GO INSERT INTO dbo.table1 VALUES (1, 'Fred') ,(2, 'Tom') ,(3, 'Sally') ,(4, 'Alice'); GO DECLARE @MyTableVar TABLE ( id INT, employee VARCHAR(32) ); PRINT 'table1, before delete' SELECT * FROM dbo.table1; DELETE FROM dbo.table1 OUTPUT DELETED.* INTO @MyTableVar WHERE id = 4 OR id = 2; PRINT 'table1, after delete' SELECT * FROM dbo.table1; PRINT '@MyTableVar, after delete' SELECT * FROM @MyTableVar; DROP TABLE dbo.table1;
Att.
Marcelo Fernandes
MCP, MCDBA, MCSA, MCTS, MCITP, MCT.
Se útil, classifique!!!
Me siga no twitter: @marcelodba- Sugerido como Resposta Junior Galvão - MVPMVP quinta-feira, 15 de janeiro de 2015 17:49
- Marcado como Resposta Ricardo Barbosa Cortes sexta-feira, 16 de janeiro de 2015 13:15
-
-
Bom dia Emerson,
Que bom que você ficou satisfeito, como você não marcou como resposta irei marcar para fechar a thread beleza?
Abraço
Ricardo Cortes Microsoft Contingent Staff
Esse contedo e fornecido sem garantias de qualquer tipo, seja expressa ou implicita.
MSDN Community Support