这是表格的结构:Id Name ParentId
ParentId
是主要列Id
的外键。现在假设我有几行如下:(仅显示行中的ParentId
)
01
/ \
5 2
/ \
3 4
我已设置InsteadOfDelete
触发器,如下所示:
CREATE TRIGGER [dbo].[tr_tb] ON [dbo].[Some_tb]
INSTEAD OF DELETE
AS
/*Delete from another table*/
DELETE FROM SomeOther_tb WHERE OtherId IN(SELECT Id FROM deleted);
/*Delete childs from this table*/
DELETE FROM Some_tb WHERE ParentId IN(SELECT Id FROM deleted);
/*Delete from this table*/
DELETE FROM Some_tb WHERE Id IN(SELECT Id FROM deleted);
删除带有Id = 01
的记录(检查上面孩子的表示)时。仅删除直接子项(Id=5,2
),留下子子记录(Id = 3,4
)。
我假设没有为孩子(InsteadOfTrigger
)触发Id=5,2
个功能。
如何解决此问题,以便删除所有嵌套的子项?
答案 0 :(得分:2)
CREATE TRIGGER [dbo].[tr_tb] ON [dbo].[Some_tb]
INSTEAD OF DELETE
AS
DECLARE @DELETED TABLE(
ID BIGINT
)
INSERT INTO @DELETED
SELECT Id FROM deleted
--could use a CTE here as well for better performance
WHILE @@ROWCOUNT>0
BEGIN
INSERT INTO @DELETED
SELECT Id
FROM Some_tb t
inner join @DELETED d on d.parentid=t.id
END
/*Delete from another table*/
DELETE FROM SomeOther_tb WHERE OtherId IN(SELECT Id FROM @DELETED);
/*Delete childs from this table*/
DELETE FROM Some_tb WHERE ParentId IN(
SELECT Id FROM @DELETED WHERE ID NOT IN (SELECT ID FROM DELETED)
);
/*Delete from this table*/
DELETE FROM Some_tb WHERE Id IN(SELECT Id FROM DELETED);
答案 1 :(得分:1)
MS SQL Server 2008支持通用表表达式(CTE),它们非常适合分层数据。并且CTE也可能存在于触发器中。
CREATE TRIGGER [dbo].[tr_tb] ON [dbo].[Some_tb]
INSTEAD OF DELETE
AS
/*Delete from another table*/
;with tbl as (--this is CTE
--anchor query (top level)
select t.id, t.parentid
from someOther_tb t
inner join deleted d on d.id = t.parentid
union all
--recursive query
select t.id, t.parentid
from someOther_tb t
inner join tbl on tbl.id=t.parentid
)
delete someOther_tb
where id in (select id from tbl)
--Now it is safe to delete from main table
DELETE FROM Some_tb WHERE Id IN(SELECT Id FROM deleted)
答案 2 :(得分:0)
$user->newSubscription('premium','monthly')->trialDays(5)->create($stripeToken,['email' => $user->email], "")