如何删除父记录和子记录

时间:2010-06-04 03:46:23

标签: sql sql-server

我有一个具有LibraryID和LibraryParentID的表。

LibraryID int Unchecked
Name varchar(50) Checked
Description varchar(200) Checked
LibraryLevel int Checked
LibraryParentID int Checked
LibraryTypeID int Unchecked 

我想编写一个sql来删除currrent select parent以及所有子记录,我该怎么做?

3 个答案:

答案 0 :(得分:2)

将外键上的删除级联 这是参考http://msdn.microsoft.com/en-us/library/aa933119(SQL.80).aspx


编辑:

评论如下。

“由单个DELETE或UPDATE触发的一系列级联引用操作必须形成一个不包含循环引用的树。在DELETE或UPDATE产生的所有级联引用操作的列表中,任何表都不能出现多次“。引自MSDN

但是这里有一些tsql可以提供帮助

Create Procedure RecursiveDelete(
 LibraryId Int )
AS
Declare @CursorLibraryID Int;

Declare myCursor Cursor FOR
SELECT LibraryParentID from Table;

Open myCursor;

Fetch Next
From MyCursor
Into @CursorLibraryID

While (@@Fetch_Status = 0) BEGIN
  Exec RecursiveDelete(@CursorLibraryID)
  Delete From Table
  Where LibraryID = @CursorLibraryId
Fetch Next
From MyCursor
Into CursorLibraryID

END

好吧,它已经很晚了,所以如果语法错误,我会道歉。但这里的想法是你有孩子,父母,祖父母,伟大的父母......等你必须递归删除它们。

答案 1 :(得分:1)

要删除库和所有父库,假设外键是自引用,您可以

WITH LibAncestors(libraryID, parentID, level) AS
(
  SELECT libraryID, libraryID, 0
  FROM   Library
  UNION ALL
   SELECT     a.libraryID, b.libraryParentID, a.level+1
   FROM   LibAncestors AS a INNER JOIN Library b
     ON b.libraryID = a.parentID
)
DELETE FROM Library 
 WHERE libraryID IN 
    (SELECT LibraryParentID FROM LibAncestors WHERE LibraryID=?)

在这?是您的LibraryID要删除的占位符,它是父级,它是父级,依此类推。

CTE在第一列中返回一个libraryID,在第二列中返回所有祖先(包括库本身)。

第3列是父母与孩子的距离。 0代表孩子本身,1代表它的父母,2代表它的祖父母,依此类推。如果您不想删除所有父项,则可以在WHERE子句中指定限制。例如,删除子项并且只是它的直接父项(在问题中指定)

DELETE FROM Library 
 WHERE libraryID IN 
    (SELECT LibraryParentID FROM LibAncestors WHERE LibraryID=? AND level<=1)

我不知道这是否适用于从libraryID到libraryParentID定义的外键。但您可以使用

禁用密钥检查并重新启用它
ALTER TABLE Library NOCHECK CONSTRAINT ALL
DELETE FROM Library ....
ALTER TABLE Library CHECK CONSTRAINT ALL

答案 2 :(得分:0)

假设您在启用关系时没有级联删除,则需要在两个语句中执行此操作:

Delete Table
Where LibraryParentId = @Param

Delete Table
Where Id = @Param