Удаление строки SQL, игнорирующей все внешние ключи и ограничения - PullRequest
33 голосов
/ 08 декабря 2009

У меня есть строка в таблице. В этой строке есть столбец идентификатора, на который ссылаются несколько других таблиц с миллионами строк. Оператор SQL для удаления строки всегда истекает. Из моего дизайна я знаю, что строка, которую я хочу удалить, никогда не упоминается где-либо еще. Следовательно, я хотел бы, чтобы SQL игнорировал необходимость проверять все другие таблицы на наличие ссылки на внешний ключ для этой строки и немедленно удалял строку. Есть ли быстрый способ сделать это в SQL 2008? Возможно, что-то вроде:

DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS

Или что-то в этом роде.

Ответы [ 8 ]

47 голосов
/ 08 декабря 2009

Вы можете установить ограничения для этой таблицы / столбца, чтобы они не проверялись временно, а затем снова включить ограничения. Общая форма будет:

ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName

Затем снова включите все ограничения с помощью

ALTER TABLE TableName CHECK CONSTRAINT ConstraintName

Полагаю, это будет временно? Вы, очевидно, не захотите делать это последовательно.

23 голосов
/ 08 декабря 2009

Да, просто запустите

DELETE FROM myTable where myTable.ID = 6850

И ДАВАЕМ ДВИГАТЕЛЬ ПРОВЕРИТЬ ОГРАНИЧЕНИЯ .

Если вы пытаетесь быть «умным» и отключаете ограничения, вы заплатите огромную цену: для включения ограничений необходимо проверять каждую строку вместо той, которую вы только что удалили. SQL хранит внутренние флаги, чтобы знать, является ли ограничение «доверенным» или нет. Ваша «оптимизация» приведет либо к изменению этих флагов на «ложь» (что означает, что SQL больше не доверяет ограничениям), либо к необходимости повторной проверки их с нуля.

См. Рекомендации по отключению индексов и ограничений и Ненадежные ограничения и производительность .

Если вы не провели некоторые твердые измерения, которые продемонстрировали, что проверка ограничения операции DELETE является узким местом производительности, пусть двигатель выполнит свою работу.

6 голосов
/ 08 декабря 2009

Ни при каких обстоятельствах не отключайте ограничения. Это чрезвычайно глупая практика. Вы не можете поддерживать целостность данных, если делаете такие вещи. Целостность данных - это первое рассмотрение базы данных, потому что без нее у вас ничего нет.

Правильный метод - удалить из дочерних таблиц, прежде чем пытаться удалить родительскую запись. Вероятно, у вас истекло время ожидания, потому что вы установили каскадные дельты, что является еще одной плохой практикой в ​​большой базе данных.

3 голосов
/ 21 января 2018

Я знаю, что это старый поток, но я попал сюда, когда удаление моей строки было заблокировано ограничениями внешнего ключа. В моем случае мой дизайн таблицы допускал значения NULL в ограниченном столбце. В удаляемых строках я изменил значение ограниченного столбца на «NULL» (что не нарушает ограничение внешнего ключа), а затем удалил все строки.

3 голосов
/ 31 октября 2014

Я хотел удалить все записи из обеих таблиц, потому что это были все тестовые данные. Я использовал SSMS GUI для временного отключения ограничения FK, затем запустил запрос DELETE для обеих таблиц и, наконец, снова включил ограничение FK.

Чтобы отключить ограничение FK:

  1. развернуть объект базы данных [1]
  2. развернуть объект зависимой таблицы [2]
  3. разверните папку 'Keys'
  4. щелкните правой кнопкой мыши по внешнему ключу
  5. выберите опцию «Изменить»
  6. изменить параметр «Принудительное ограничение внешнего ключа» на «Нет»
  7. закрыть окно «Отношения по внешнему ключу»
  8. закрыть вкладку дизайнера таблиц
  9. при появлении запроса подтверждения сохранения изменений
  10. выполнить необходимые запросы на удаление
  11. повторно включить ограничение внешнего ключа так же, как вы только что отключили его.

[1] на панели «Обозреватель объектов». Доступ к ним можно получить через пункт меню «Вид» или клавишу F8

.

[2], если вы не уверены, какая таблица является зависимой, вы можете проверить, щелкнув правой кнопкой мыши по соответствующей таблице и выбрав опцию «Просмотр зависимостей».

1 голос
/ 08 декабря 2009

Во всех таблицах с внешними ключами, указывающими на эту, используйте:

ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name
0 голосов
/ 26 апреля 2018
SET FOREIGN_KEY_CHECKS = 0;

/ * Запустите ваш скрипт * /

SET FOREIGN_KEY_CHECKS = 1;

Посмотрите, поможет ли это, Это для игнорирования проверок foreign key. Но удаление отключения это очень плохая практика.

0 голосов
/ 08 декабря 2009

Вы можете отключить и снова включить ограничения:

http://sqlforums.windowsitpro.com/web/forum/messageview.aspx?catid=60&threadid=48410&enterthread=y

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...