在多对多关系中删除相关行
在多对多关系中删除相关行
我正在删除一个位于多对多关系的一侧的表中的一行数据。我还想删除与该关系的另一侧相关的任何行。
例如,假设我有以下表,并且我想从Cars
中删除一行。我还想删除Drivers
中的任何相关行,当然也要删除CarDrivers
中不再需要的任何行。
表 Cars: CarID int CarName nvarchar(100) 表 Drivers: DriverID int DriverName nvarchar(100) 表 CarDrivers: CarID int Driver int
我知道如何在SELECT
查询中连接这些表。但我不知道如何跨关系删除数据。
注意:关系的双方都实现了级联删除。因此,例如,从Cars
中删除一行将删除CarDrivers
中的任何相关行。但显然这不会传播到Drivers
表中。
在一个多对多的关系中,驱动员表和汽车表之间没有直接的关联关系。这个关系是通过CarDrivers表来实现的。因此,问题仍然存在。
我所知道的唯一自动化级联删除的方法是,删除CarDrivers表和Drivers表之间的外键,并在CarDrivers表上添加一个在删除之前或之后触发的触发器,以删除在drivers表中driver_id为被删除的CarDrivers表中的行之一的条目。
这种方法在很多方面都不够清洁。如果实际上需要通过连接表进行删除操作,那么关系可能被建模错误,一个更清晰的关系应该是将关系简单地建模为“一辆车有多个驱动员”或在Drivers表中有一个Cars的外键。正如上面所提到的,对于实际的汽车和驱动员关系,多对多的关系是正确的,你永远不会因为汽车被报废/删除而删除一个驱动员。
在一个多对多的关系中删除相关行的原因可能是因为请求不合理,或者设计问题导致了无法直接删除一个表中的记录。解决方法可以是通过在关联表上使用触发器,来实现级联删除其他相关行。以下是一种可能的解决方案:
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 表之间的外键,而不是在关联表中。这样可以实现 "每辆车最多只有一个驾驶员" 的限制。
总之,以上是一个可能的解决方案,但需要根据具体的表结构和需求来进行调整和优化。
在一个多对多的关系中,删除相关的行可能会导致一些问题。最好的方法是首先删除相关表的数据。换句话说,如果您想要删除一辆汽车以及使用该汽车的相关司机,您必须先删除司机,然后再删除汽车。由于使用了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
,您可以使用任何值,包括参数,如果您将此代码片段用于存储过程中。