我有三张桌子
GroupTable
GroupId
Name
每个群组都有一对多的用户
Users
UserId
Name
GroupId
每个用户都有一对多的挑战'
Challenges
Name
UserId
我希望能够删除分配给该特定群组的用户的群组
我试过这个,我设法根据id删除了组而没有获得外键约束错误但是所有用户都添加到用户表中并且所有挑战都被删除了
ALTER TABLE GroupTable NOCHECK CONSTRAINT ALL
ALTER TABLE UserTable NOCHECK CONSTRAINT ALL
ALTER TABLE Challanges NOCHECK CONSTRAINT ALL
DELETE FROM GroupTable
WHERE ID = @GroupId
DELETE FROM child
FROM Challanges as child
INNER JOIN UserTable AS parent
ON child.UserId = parent.ID
WHERE parent.GroupId = @GroupId
DELETE FROM parent
FROM UserTable AS parent
WHERE GroupId = GroupId
我如何修改上述内容,以便我只删除特定用户的gropu以及分配给集团的挑战?
答案 0 :(得分:2)
不要为此禁用约束,因为它会影响数据完整性
在外键上使用on delete cascade
选项,或在单个事务中以正确的顺序从所有三个表中删除数据。
要将on cascade delete
添加到现有外键,必须使用alter table
语句删除现有约束,然后使用on delete cascade
选项再次添加它:
ALTER TABLE table_name
DROP CONSTRAINT constraint_name
ALTER TABLE table_name
ADD CONSTRAINT constraint_name
FOREIGN KEY (column_name)
REFERENCES other_table_name(other_column_name) ON DELETE CASCADE
(当然,这可以完成using ssms's design table window)
以正确的顺序从相关表中删除行将确保您不会遇到现有外键约束的问题,将所有delete语句包装在单个事务中将确保您只删除每个表或根本不删除任何表:
DECLARE @GroupId int = 5
BEGIN TRY
BEGIN TRANSACTION
DELETE c
FROM Challanges c
INNER JOIN UserTable u ON(c.UserId = u.UserId)
WHERE u.GroupId = @GroupId
DELETE
FROM Users
WHERE GroupId = @GroupId
DELETE
FROM GroupTable
WHERE ID = @GroupId
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
END CATCH