每次应用程序执行某些删除操作时,我都必须执行以下存储过程。我的问题是,如果你们中的任何人都知道某种方式,加快这个存储过程。
DECLARE @CID UNIQUEIDENTIFIER
SET @CID = @CategoryId
DELETE FROM Elements
WHERE CategoryId = @CID
AND ParentId IS NOT NULL
AND ParentId NOT IN (SELECT ElementId FROM Elements WHERE CategoryId = @CID)
WHILE (@@ROWCOUNT > 0)
BEGIN
DELETE FROM Elements
WHERE CategoryId = @CID
AND ParentId IS NOT NULL
AND ParentId NOT IN (SELECT ElementId FROM Elements WHERE CategoryId = @CID)
END
这里的结构:
Element 1
Element 2
Element 2.1
Element 2.2
Element 2.3
Element 2.3.1
Element 2.3.2
Element 3
...
例如,如果删除“元素2”,则也必须删除所有子元素。
查询的工作原理: 如果我删除“元素2”并执行存储过程,则第一个删除语句将删除“元素2.1”,“元素2.2”和“元素2.3”,因为无法找到其ParentId(“元素2”的ElementId)在表中。之后,将执行第二个删除语句。这次同一语句找不到之前删除执行的元素的任何ElementIds。
重要: 在执行存储过程之前,应用程序已删除一个元素。之后,整个结构将被保存。之后,所有父项不存在的元素将被存储过程删除。
环境是SQL Server 2008 R2。 提前谢谢!
安德烈
答案 0 :(得分:0)
试试这个解决方案 -
SET NOCOUNT ON;
DECLARE @Node NVARCHAR(50)
SELECT @Node = 'Element 2.3'
DECLARE @temp TABLE
(
Node NVARCHAR(50) PRIMARY KEY
, ParentNode NVARCHAR(50) NULL
)
INSERT INTO @temp (Node, ParentNode)
VALUES
('Element 1', NULL),
('Element 2', NULL),
('Element 2.1', 'Element 2'),
('Element 2.2', 'Element 2'),
('Element 2.3', 'Element 2'),
('Element 2.3.1', 'Element 2.3'),
('Element 2.3.2', 'Element 2.3'),
('Element 3', NULL)
; WITH nodes (Node) AS
(
SELECT d.Node
FROM @temp d
WHERE d.Node = @Node
UNION ALL
SELECT d.Node
FROM @temp d
JOIN nodes d3 ON d3.Node = d.ParentNode
)
DELETE FROM t
FROM @temp t
JOIN nodes n ON t.Node = n.Node
SELECT *
FROM @temp