我有2个SQL Server表(A和B)。
我想从以下位置删除行: A,使用一个触发器删除B中的行时。
我想从以下位置删除行: B,使用一个触发器删除A中的行时。
到目前为止,这是我的触发器:
CREATE TRIGGER instead_delete
ON A INSTEAD of DELETE as
DELETE B
FROM B, deleted
WHERE B.Id = deleted.Id
DELETE A
FROM A, deleted
WHERE A.Id = deleted.Id
我的第二个触发器:
CREATE TRIGGER after_delete
ON B AFTER DELETE as
DELETE A
FROM A, deleted
WHERE A.Id = deleted.Id
但它无法正常工作。 我得到一个直接的递归。 (而不是触发器不支持直接递归。触发器执行失败 - 这个错误)。
我该如何解决?
答案 0 :(得分:0)
我想删除具有外键约束的自引用表中的记录层次结构。使用AFTER DELETE触发器不起作用,因为在它到达之前违反了外键约束。使用INSTEAD OF触发器不起作用,因为它抛出“INSTEAD OF触发器不支持直接递归”错误。更改数据库的直接和间接设置无效。我找不到任何解决方案。我能想到的唯一解决方案是使用CTE选择层次结构中具有深度/级别编号的所有记录,并使用光标从最大深度逐个删除记录以避免外键冲突。以下是示例触发器:
CREATE TRIGGER [dbo].[relatedAccountInsteadOfDelete]
ON [dbo].[relatedAccount]
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;
-- log deleted related accounts
with relatedAccounts as (
select
ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
deleted d
on
d.[guid] = ra1.[guid]
union all
select
ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
relatedAccounts ra2
on
ra2.[guid] = ra1.relatedAccount_guid
where
ra1.relatedAccount_guid is not null
)
insert into relatedAccount_history select ra1.* from relatedAccount ra1 inner join relatedAccounts ra2 on ra2.[guid] = ra1.[guid];
-- delete related entities
with relatedAccounts as (
select
ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
deleted d
on
d.[guid] = ra1.[guid]
union all
select
ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
relatedAccounts ra2
on
ra2.[guid] = ra1.relatedAccount_guid
where
ra1.relatedAccount_guid is not null
)
delete from dbo.relatedEntity where [guid] in (select t1.[guid] from relatedAccounts d inner join dbo.relatedEntity t1 on t1.relatedAccount_guid=d.[guid]);
-- delete related accounts
declare @guid uniqueidentifier;
-- select all accounts to any depth in their hierarchy
declare relatedAccounts_cursor cursor for
with relatedAccounts as (
select
1 as depth
,ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
deleted d
on
d.[guid] = ra1.[guid]
union all
select
ra2.depth + 1 as depth
,ra1.[guid]
,ra1.relatedAccount_guid
from
relatedAccount ra1
inner join
relatedAccounts ra2
on
ra2.[guid] = ra1.relatedAccount_guid
where
ra1.relatedAccount_guid is not null
)
select [guid] from relatedAccounts order by depth desc;
-- delete accounts from the bottom up to avoid violating foriegn key constraints
open relatedAccounts_cursor
fetch next from relatedAccounts_cursor
into @guid
while @@fetch_status = 0
begin
delete from dbo.relatedAccount where [guid] = @guid;
fetch next from relatedAccounts_cursor
into @guid
end
close relatedAccounts_cursor;
deallocate relatedAccounts_cursor;
END