我有一个具有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以及所有子记录,我该怎么做?
答案 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