Удаление строки SQL, игнорирующей все внешние ключи и ограничения
У меня есть строка в таблице. Эта строка имеет столбец идентификатора, указанный в нескольких других таблицах с миллионами строк. Оператор SQL для удаления строки всегда отключается. Из моего дизайна я знаю, что строка, которую я хочу удалить, никогда не упоминается нигде. Поэтому я бы хотел, чтобы SQL игнорировал необходимость проверки всех других таблиц для ссылки на внешний ключ для этой строки и немедленно удалить строку. Есть ли быстрый способ сделать это в SQL 2008?
Возможно, что-то вроде:
DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS
Или что-то в этом роде.
Ответы
Ответ 1
Вы можете установить ограничения на эту таблицу/столбец, чтобы временно не проверять, а затем снова включить ограничения. Общая форма:
ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName
Затем снова включите все ограничения с помощью
ALTER TABLE TableName CHECK CONSTRAINT ConstraintName
Я предполагаю, что это было бы временно? Вы, очевидно, не хотели бы делать это последовательно.
Ответ 2
Да, просто запустите
DELETE FROM myTable where myTable.ID = 6850
И ПОЛУЧИТЕ ДВИГАТЕЛЬ, ПРОВЕРЬТЕ КОНТРАКТЫ.
Если вы пытаетесь быть "умными" и отключать ограничения, вы заплатите огромную цену: включение обратно ограничений должно проверять каждую строку вместо той, которую вы только что удалили. Существуют внутренние флаги SQL, которые знают, что ограничение "доверено" или нет. Вы - "оптимизация", приведет либо к изменению этих флагов на "false" (что означает, что SQL больше не доверяет ограничениям), либо он должен перепроверить их с нуля.
См. Рекомендации по отключению индексов и ограничений и Неверные ограничения и производительность.
Если вы не выполнили измерения solid, которые продемонстрировали, что проверка ограничения операции DELETE является узким местом производительности, пусть двигатель выполняет свою работу.
Ответ 3
Ни в коем случае не запрещайте ограничения. Это очень глупая практика. Вы не можете поддерживать целостность данных, если вы так делаете. Целостность данных является первым рассмотрением базы данных, потому что без нее у вас ничего нет.
Правильный метод - удалить из дочерних таблиц, прежде чем пытаться удалить родительскую запись. Вероятно, вы выбрали время, потому что вы создали каскадные дельта, что является другой плохой практикой в большой базе данных.
Ответ 4
Возможно, вы можете отключить и снова включить ограничения:
http://sqlforums.windowsitpro.com/web/forum/messageview.aspx?catid=60&threadid=48410&enterthread=y
Ответ 5
Во всех таблицах с внешними ключами, указывающими на это, используйте:
ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name
Ответ 6
Я хотел удалить все записи из обеих таблиц, потому что это были все тестовые данные. Я использовал SSMS GUI, чтобы временно отключить ограничение FK, затем я выполнил запрос DELETE в обеих таблицах и, наконец, снова включил ограничение FK.
Чтобы отключить ограничение FK:
- развернуть объект базы данных [1]
- развернуть зависимый объект таблицы [2]
- разверните папку "Ключи"
- щелкните правой кнопкой мыши по внешнему ключу.
- выберите вариант "Изменить"
- измените параметр "Принудительное ограничение внешнего ключа" на "Нет"
- закрыть окно "Внешние ключи"
- закрыть вкладку конструктора таблиц.
- при запросе подтверждения сохранения изменений
- выполнить необходимые запросы на удаление
- повторно включить ограничение внешнего ключа так же, как вы его отключили.
[1] на панели "Проводник объектов" можно получить доступ через меню "Вид" или клавишу F8
[2], если вы не знаете, какая таблица является зависимой, вы можете проверить, щелкнув правой кнопкой мыши на соответствующей таблице и выбрав параметр "Зависимости от просмотра".