在多对多关系中删除相关行

27 浏览
0 Comments

在多对多关系中删除相关行

我正在删除一个位于多对多关系的一侧的表中的一行数据。我还想删除与该关系的另一侧相关的任何行。

例如,假设我有以下表,并且我想从Cars中删除一行。我还想删除Drivers中的任何相关行,当然也要删除CarDrivers中不再需要的任何行。

表 Cars:
CarID      int
CarName    nvarchar(100)
表 Drivers:
DriverID   int
DriverName nvarchar(100)
表 CarDrivers:
CarID      int
Driver     int

我知道如何在SELECT查询中连接这些表。但我不知道如何跨关系删除数据。

注意:关系的双方都实现了级联删除。因此,例如,从Cars中删除一行将删除CarDrivers中的任何相关行。但显然这不会传播到Drivers表中。

0
0 Comments

在一个多对多的关系中,驱动员表和汽车表之间没有直接的关联关系。这个关系是通过CarDrivers表来实现的。因此,问题仍然存在。

我所知道的唯一自动化级联删除的方法是,删除CarDrivers表和Drivers表之间的外键,并在CarDrivers表上添加一个在删除之前或之后触发的触发器,以删除在drivers表中driver_id为被删除的CarDrivers表中的行之一的条目。

这种方法在很多方面都不够清洁。如果实际上需要通过连接表进行删除操作,那么关系可能被建模错误,一个更清晰的关系应该是将关系简单地建模为“一辆车有多个驱动员”或在Drivers表中有一个Cars的外键。正如上面所提到的,对于实际的汽车和驱动员关系,多对多的关系是正确的,你永远不会因为汽车被报废/删除而删除一个驱动员。

0
0 Comments

在一个多对多的关系中删除相关行的原因可能是因为请求不合理,或者设计问题导致了无法直接删除一个表中的记录。解决方法可以是通过在关联表上使用触发器,来实现级联删除其他相关行。以下是一种可能的解决方案:

CREATE TRIGGER delete_car_drivers
BEFORE DELETE ON Drivers
FOR EACH ROW
BEGIN
  DELETE FROM CarDrivers WHERE DriversId = OLD.Id;
END;

这段代码创建了一个触发器,在删除 Drivers 表中的记录之前,会自动删除 CarDrivers 表中与该记录相关的行。这样就实现了级联删除的效果。

需要注意的是,这个解决方案可能会导致触发器的递归调用,具体取决于触发器的默认行为设置。

另外,如果在多对多的关联表中某一列设置了唯一性约束,那么这个列应该是 Cars 表和 Drivers 表之间的外键,而不是在关联表中。这样可以实现 "每辆车最多只有一个驾驶员" 的限制。

总之,以上是一个可能的解决方案,但需要根据具体的表结构和需求来进行调整和优化。

0
0 Comments

在一个多对多的关系中,删除相关的行可能会导致一些问题。最好的方法是首先删除相关表的数据。换句话说,如果您想要删除一辆汽车以及使用该汽车的相关司机,您必须先删除司机,然后再删除汽车。由于使用了ON CASCADE DELETE,连接表将删除正确的记录。

尝试以下代码:

delete
from Drivers
where DriverID in
(
    select d.DriverID
    from Drivers d
    inner join CarDrivers cd
    on d.DriverID = cd.Driver
    inner join Cars c
    on c.CarID = cd.CarID
    where c.CarID = 1
)
delete
from Cars
where CarID = 1

当然,您不需要在这里硬编码1,您可以使用任何值,包括参数,如果您将此代码片段用于存储过程中。

0