我花了很多时间试图弄清楚如何在SQL Server上实现递归主键的 CASCADE ON DELETE 一段时间了。我已经阅读了有关触发器,创建临时表等的信息,但还没有找到适用于我的数据库设计的答案。
这是一个Boss / Employee数据库示例,可用于演示目的:
TABLE employee
id|name |boss_id
--|---------|-------
1 |John |1
2 |Hillary |1
3 |Hamilton |1
4 |Scott |2
5 |Susan |2
6 |Seth |2
7 |Rick |5
8 |Rachael |5
正如您所看到的,每个员工都有一个也是员工的老板。所以,id / boss_id上存在PK / FK关系。
这是一个(缩写)表及其信息:
TABLE information
emp_id|street |phone
------|-----------|-----
2 |blah blah |blah
6 |blah blah |blah
7 |blah blah |blah
employee.id/information.emp_id上有一个PK / FK,CASCADE ON DELETE。
例如,如果Rick被解雇,我们会这样做:
DELETE FROM employee WHERE id=7
这应该从员工和信息中删除Rick的行。 Yay级联!
现在,说我们经历了艰难时期,我们需要打下汉密尔顿和他的整个部门。这意味着我们需要删除
我们运行时从员工和信息表中:
DELETE FROM employee WHERE id=3
我为id / emp_id尝试了一个简单的CASCADE ON DELETE,但是SQL Server没有它:
Introducing FOREIGN KEY constraint 'fk_boss_employee' on table 'employee' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
我能够在Access中的测试数据库上使用CASCADE ON DELETE,它的行为完全符合我的要求。同样,如果父母,祖父母,曾祖父母等被删除,我想要父母的每个可能的孩子,孙子,曾孙等都要删除。
当我尝试使用触发器时,我似乎无法触发它(例如,当你试图删除汉密尔顿的员工Susan时,先看看Susan是否有员工等)更不用说降低N-number员工。
原来如此!我想我已经提供了我能想到的每一个细节。如果某些事情仍然不明确,我会尝试改进这种描述。
答案 0 :(得分:5)
Necromancing。
有两个简单的解决方案。
或
PS:这是讽刺。
答案 1 :(得分:3)
以下内容可能对您有用(我还没有对其进行测试,因此可能需要进行一些调整)。似乎所有你要做的就是删除层次结构底部的员工,然后再删除更高层次的员工。使用CTE以递归方式构建删除层次结构,并按员工的层次结构级别对CTE输出进行排序。然后按顺序删除。
CREATE PROC usp_DeleteEmployeeAndSubordinates (@empId INT)
AS
;WITH employeesToDelete AS (
SELECT id, CAST(1 AS INT) AS empLevel
FROM employee
WHERE id = @empId
UNION ALL
SELECT e.id, etd.empLevel + 1
FROM employee e
JOIN employeesToDelete etd ON e.boss_id = etd.id AND e.boss_id != e.id
)
SELECT id, ROW_NUMBER() OVER (ORDER BY empLevel DESC) Ord
INTO #employeesToDelete
FROM employeesToDelete;
DECLARE @current INT = 1, @max INT = @@ROWCOUNT;
WHILE @current <= @max
BEGIN
DELETE employee WHERE id = (SELECT id FROM #employeesToDelete WHERE Ord = @current);
SET @current = @current + 1;
END;
GO
答案 2 :(得分:1)
这可能听起来很极端,但我不认为你想要做的事情有一个简单的烘焙选项。我建议创建一个可以执行以下操作的proc:
将整个事物包裹在事务中以保持一致性