我写了一个存储过程。 现在我看,这是非常糟糕的表现。 我认为这是因为while循环。
ALTER PROCEDURE [dbo].[DeleteEmptyCatalogNodes]
@CatalogId UNIQUEIDENTIFIER,
@CatalogNodeType int = null
AS
BEGIN
SET NOCOUNT ON;
DECLARE @CID UNIQUEIDENTIFIER
DECLARE @CNT int
SET @CID = @CatalogId
SET @CNT = @CatalogNodeType
DELETE cn FROM CatalogNodes cn
LEFT JOIN CatalogNodes as cnj on cn.CatalogNodeId = cnj.ParentId
LEFT JOIN CatalogArticles as ca on cn.CatalogNodeId = ca.CatalogNodeId
WHERE cn.CatalogId = @CID
AND cnj.CatalogNodeId IS NULL
AND ca.ArticleId IS NULL
AND (cn.CatalogNodeType = @CNT OR @CNT IS NULL)
WHILE (@@ROWCOUNT > 0)
BEGIN
DELETE cn FROM CatalogNodes cn
LEFT JOIN CatalogNodes as cnj on cn.CatalogNodeId = cnj.ParentId
LEFT JOIN CatalogArticles as ca on cn.CatalogNodeId = ca.CatalogNodeId
WHERE cn.CatalogId = @CID
AND cnj.CatalogNodeId IS NULL
AND ca.ArticleId IS NULL
AND (cn.CatalogNodeType = @CNT OR @CNT IS NULL)
END
END
你们中的任何人都可以给我一个关于如何做到更像“设置”的暗示吗?
非常感谢!
编辑评论和回答:
这些表的构建如下:
CatalogNodes:
CatalogNodeId|ParentId|Name
1|NULL|Root
2|1|Node1
3|1|Node2
4|2|Node1.1
CatalogArticles:
CatalogNodeId|Name
3|Article1
3|Article2
3|Article3
调用SP后,必须删除Node1和Node1.1。 在第一个删除语句中,将删除Node1.1。 在While循环中,Node1将被删除。 我希望我的问题现在更容易理解,它是一种树形结构。
答案 0 :(得分:1)
您只需要WHILE部分,因为所有匹配的行都将从第一个DELETE语句中删除
答案 1 :(得分:1)
你的循环没有做任何事情......第一个删除语句将删除一些记录,如果有任何符合你的where条件...所以@@ rowcount将大于0但不会是循环内第二个删除语句中要删除的任何记录。还是我错过了什么?
无论如何我不认为连续两次执行删除会对性能产生很大影响......如果你查看查询计划,你应该看到它...
答案 2 :(得分:0)
在我看来,这样做的一种方法是创建一个表变量并将所有必须删除的元素放在那里,并使用i和join在一个语句中进行删除。
答案 3 :(得分:0)
CatalogNodes是您要删除的内容。创建一个select,它可以提取您想要删除的所有CatalogNodes。如果存在与外键约束相关的事物则首先删除它们,最后一旦它们全部删除了删除CatalogNodes。临时表可以在这里受益,因为它们存放在记忆中。