当前位置: 首页 > 面试题库 >

SQL Server-使用递归外键级联删除

鞠子轩
2023-03-14
问题内容

我花了很多时间试图弄清楚如何在一段时间内为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。

例如,如果瑞克被解雇,我们可以这样做:

DELETE FROM employee WHERE id=7

这应该从员工和信息中删除Rick的行。耶级联!

现在,说我们经历了艰难的时期,我们需要解雇汉密尔顿及其 整个 部门。这意味着我们将需要删除

  • 汉密尔顿
  • 史考特
  • 苏珊
  • 赛斯
  • 里克
  • 雷切尔

当我们运行时,从employee和information表中:

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,它的行为完全符合我的期望。再次,我 希望
删除父母的所有可能的孩子,孙子,曾孙等,如果他们的父母,祖父母,曾祖父母等被删除。

当我尝试使用触发器时,我似乎无法使其触发自身(例如,当您尝试删除汉密尔顿的雇员苏珊,首先查看苏珊是否有任何雇员,等等),更不用说减少N个雇员了。

所以!我想我已经提供了我能想到的所有细节。如果仍然不清楚,我将尝试改进此描述。


问题答案:

以下内容可能对您有用(我尚未测试过,因此可能需要进行一些调整)。似乎您要做的就是从层次结构的底部删除雇员,然后再删除较高的雇员。使用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


 类似资料:
  • 问题内容: 我有两个像这样的表: 因此,逻辑很简单,用户删除了类别x下​​的所有书籍,从猫中删除了x之后,我尝试了上述方法,但不起作用,在我清理了表格书籍后,表格类别仍被填充,这是怎么回事? 问题答案: 具有级联删除功能的外键意味着,如果删除父表中的记录,则子表中的相应记录将被自动删除。这称为级联删除。 您说的是相反的意思,这不是当您从子表中删除时会将记录从父表中删除。 ON DELETE CAS

  • 问题内容: 我想使用外键来保持完整性并避免使用孤立键(我已经使用过innoDB)。 如何创建在CASCADE上删除的SQL语句? 如果我删除一个类别,那么如何确保它不会删除也与其他类别相关的产品。 数据透视表“ categories_products”在其他两个表之间创建多对多关系。 问题答案: 如果您的级联删除某个产品是因为该产品属于被杀类别的成员,那么它会删除该产品,那么您的外键设置不正确。给

  • 问题内容: 我有以下示例: 我想在级联排如果双方并从各自的表被删除。 删除两个外键后,如何在表C中级联自身? 如果仅删除一个FK,则受影响的行应在引用该外键的列中更改为空值。 问题答案: 我建议使用两个外键约束和一个触发器来处理其余的 表格: 扳机: SQL提琴。 确保连接表具有替代PK列。无论如何都不能是PK,因为那将不允许两者都为NULL。而是添加一个约束,该约束允许使用NULL值。 触发器针

  • 在数据库中,将有一个列,并对的列具有外键约束。 对于在删除时级联的外键约束,可能执行的一些操作包括、和。这给出了以下方案组合。 a:在JPA中对父级进行级联删除调用,在删除父行时删除数据库中的子级。 b:在JPA中级联删除,在父删除时将子表中的外键列设置为null。在这种情况下,@joincolumn中的和中的可能需要为true/false。 C:在JPA中进行级联删除,在数据库中对外键删除不做任

  • Django演示了如何设置或覆盖在文档中使用外键的级联删除。 但是如果我们想让这种效果反过来呢?如果我们希望fk模型的删除导致该模型的删除,该怎么办? 谢谢

  • 问题内容: 我有两个表:航迹和航路点,一个航迹可以有多个航路点,但是航路点仅分配给1条航迹。 在点表的方式中,我有一个名为“ trackidfk”的列,一旦创建了轨道,该列就会插入track_ID,但是我没有在此列上设置外键约束。 删除轨道时,我想删除分配的航点,这可能吗?我读过有关使用触发器的信息,但我认为Android不支持它们。 要创建航点表: 问题答案: 支持带有on delete级联的外