2015-06-09 2 views
1

у меня есть три таблицыУдаление таблицы с внешними ключами constaints

GroupTable 
GroupId 
Name 

Каждая группа имеет один ко многим с пользователей

Users 
UserId 
Name 
GroupId 

И каждый пользователь имеет один ко многим с «вызовы»

Challenges 
Name 
UserId 

Я хочу, чтобы иметь возможность удалять группу с пользователями, назначенными этой конкретной группе

Я попытался это, где я все-таки удается удалить группу на основе идентификатора, не получая ошибки внешнего ключа ограничения, но все пользователи добавляются в таблицу пользователей и ВСЕ вызовы удаляются, а

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 с конкретными пользователями и возникнуть проблемы, связанные с Группой?

+1

Umm ... 'DELETE FROM parent FROM UserTable AS parent WHERE GroupId = GroupId' должен быть опечаткой? Наверняка вы хотите 'GroupId = @ GroupId'? –

+0

Только что увидел, что теперь ... это может поставить вопрос – Arianule

ответ

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 
Смежные вопросы