SQL Server: Auto-referência FK, gatilho em vez de excluir cascata
-
21-09-2019 - |
Pergunta
Preciso executar uma cascata de exclusão na minha tabela nomeada categoria, que possui o seguinte nome columls cat_id (bigint) (varchar) parent_cat_id (bigint)
Parent_cat_id é um fk em cat_id. Obviamente, o encantador servidor SQL não me permite usar na exclusão de Cascade, reivindicando caminhos circulares ou múltiplos à exclusão.
Uma solução que eu vejo frequentemente proposta são os gatilhos. Eu fiz o seguinte gatilho:
USE [ma]
GO
/****** Object: Trigger [dbo].[TRG_DELETE_CHILD_CATEGORIES] Script Date: 11/23/2009 16:47:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[TRG_DELETE_CHILD_CATEGORIES] ON [dbo].[CATEGORY] FOR DELETE AS
SET NOCOUNT ON
/* * CASCADE DELETES TO '[Tbl B]' */
DELETE CATEGORY FROM deleted, CATEGORY WHERE deleted.CAT_ID = CATEGORY.PARENT_CAT_ID
Quando excluo manualmente uma categoria com categorias infantis, recebo a seguinte exceção:
Alguma ideia do que há de errado com o meu gatilho?
ATUALIZAR:Desculpe pela edição, mas tenho outra categoria de coluna.cat_sch_id, que é um FK de outra tabela cat_sch.id. Este FK também tem uma exclusão em cascata, o que significa que, uma vez que eu excluo um CAT_SCH, suas categorias também devem ser excluídas. Então, recebo esse erro ao definir o gatilho:
Não é possível criar em vez de excluir ou em vez de atualizar o gatilho 'trg_del_category_with_children' na tabela 'categoria'. Isso ocorre porque a tabela possui uma chave estrangeira com exclusão ou atualização em cascata.
Alguma ideia?
Solução
O gatilho para excluir é aumentado depois O delete original foi executado. Para excluir recursivamente, você precisa escrever um gatilho em vez de excluir.
O algoritmo é assim:
Insira os PKs da exclusão em uma tabela de temperatura
Encontre registros detalhados dos registros na tabela Temp
Loop até que não mais registros sejam encontrados
Exclua registros na tabela juntando -se à tabela Temp.
Eu descrevi a exclusão recursiva no meu blog.
Atualizar
Eu acho que você só precisa soltar isso na bandeira de excluir em cascata da sua chave estrangeira recursiva nas categorias. A bandeira em cascata na chave estrangeira de Cat_SCH não deve importar.