SQL Server 2008以正确的顺序从自引用表中删除记录

时间:2012-08-31 15:30:29

标签: sql sql-server-2008 sql-order-by sql-delete self-reference

  

可能重复:
  SQL: DELETE data from self-referencing table in specific order

我需要从SQL Server 2008中的自引用表中删除一组子记录。我正在尝试执行以下操作,但它不喜欢顺序。

WITH SelfReferencingTable (ID, depth)
AS
(
   SELECT id, 0 as [depth]
   FROM dbo.Table
   WHERE parentItemID IS NULL AND [t].ColumnA = '123'
   UNION ALL
   SELECT [t].ID, [srt].[depth] + 1 
   FROM dbo.Table t 
   INNER JOIN SelfReferencingTable srt ON [t].parentItemID = [srt].id
   WHERE [t].ColumnA = '123'       
)   
DELETE y FROM dbo.Table y
JOIN SelfReferencingTable x on x.ID = y.id
ORDER BY x.depth DESC

为什么这不起作用?

2 个答案:

答案 0 :(得分:4)

您无需按任何特定顺序删除它们。

只需在一次操作中删除它们即可。在语句末尾检查约束。

假设您的递归CTE代码正确识别了您需要删除的所有行,您可以使用

WITH SelfReferencingTable (ID)
AS
(
   SELECT id
   FROM dbo.Table
   WHERE parentItemID IS NULL AND [t].ColumnA = '123'
   UNION ALL
   SELECT [t].ID 
   FROM dbo.Table t 
   INNER JOIN SelfReferencingTable srt ON [t].parentItemID = [srt].id
   WHERE [t].ColumnA = '123'       
)   
DELETE 
FROM dbo.Table 
WHERE ID IN (SELECT id FROM SelfReferencingTable )

答案 1 :(得分:0)

delete子句不允许order bydelete是单个原子操作,delete操作的步骤完成顺序无关紧要。

一个常见的解决方案是删除循环中没有依赖行的行:

while 1=1
    begin
    delete  yt
    from    YourTable yt
    where   where ColumnA = '123'
            and not exists
            (
            select  *
            from    YourTable yt2
            where   yt2.parentItemId = yt.id
            )

    if @@rowcount = 0
        break
    end