Я получил ошибку. Оператор DELETE конфликтует с ограничением REFERENCE.

Я попытался обрезать таблицу с внешними ключами и получил сообщение:

«Невозможно обрезать таблицу, поскольку на нее ссылается ограничение FOREIGN KEY».

Я прочитал много литературы о проблеме и подумал, что нашел решение с помощью удаления

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

Но я все еще получил сообщение об ошибке:

«Инструкция DELETE конфликтует с ограничением REFERENCE».

Когда я пытаюсь удалить с помощью Microsoft Management Studio и выполнить предыдущий запрос

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

ошибок не выдает и работает нормально. Я хочу удалить всю информацию из таблицы и добавить в нее новую, но я не хочу удалять и создавать внешние ключи.


person Peter    schedule 23.09.2010    source источник


Ответы (4)


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

Вам нужно будет либо удалить и воссоздать ограничения, либо удалить данные, на которые ссылается внешний ключ.

Предположим, у вас есть следующие таблицы

dbo.Students
(
StudentId
StudentName
StudentTypeId
)


dbo.StudentTypes
(
StudentTypeId
StudentType
)

Предположим, что существует ограничение внешнего ключа между столбцом StudentTypeId в StudentTypes и столбцом StudentTypeId в Students.

Если вы попытаетесь удалить все данные в StudentTypes, произойдет ошибка, поскольку столбец StudentTypeId в Students ссылается на данные в таблице StudentTypes.

ИЗМЕНИТЬ:

DELETE и TRUNCATE по сути делают одно и то же. Единственное отличие состоит в том, что TRUNCATE не сохраняет изменения в файле журнала. Также вы не можете использовать предложение WHERE с TRUNCATE

КАК почему вы можете запустить это в SSMS, но не через свое приложение. Я действительно не могу видеть, как это происходит. Ограничение FK по-прежнему будет вызывать ошибку независимо от того, откуда возникла транзакция.

person codingbadger    schedule 23.09.2010
comment
Спасибо, я попробую сначала удалить дочернюю таблицу, а затем основную. Будет ли это работать, если я использую TRUNCATE вместо DELETE. Можете ли вы сказать мне, почему в студии управления MS я могу удалить строки из таблицы с тем же запросом, который дает мне ошибку, когда я пытаюсь это сделать с приложением - person Peter; 23.09.2010
comment
Это далеко не единственная разница, например. truncate не может произойти, если вообще есть какие-либо ссылки. И усечение не может произойти в транзакции в большинстве систем. И усечение не может происходить как часть хранимой процедуры. И усечение должно быть в отдельном пакете в большинстве систем. И усечение не может запускать триггеры. - person Jon Hanna; 23.09.2010
comment
@Jon Hanna - Конечно, ты прав. Я должен был действительно детализировать различия. Может быть, формулировка «только разница» вводит в заблуждение. - person codingbadger; 23.09.2010
comment
В SQL Server вы можете Truncate в хранимой процедуре и/или как часть транзакции. По крайней мере, в SSMS 2012 и выше. - person Mike; 26.04.2017

Рассматривали ли вы возможность применения ON DELETE CASCADE там, где это уместно?

person annakata    schedule 23.09.2010

Вы пытаетесь удалить строку, на которую ссылается другая строка (возможно, в другой таблице).

Вам нужно сначала удалить эту строку (или, по крайней мере, переустановить ее внешний ключ на что-то другое), иначе вы получите строку, которая ссылается на несуществующую строку. База данных запрещает.

person Konrad Rudolph    schedule 23.09.2010
comment
Я решил свою проблему с удалением каждой строки из дочерней таблицы и после удаления всех строк из родительской таблицы. Но все еще есть некоторые вопросы :) например, Когда я пытаюсь удалить с помощью Microsoft Management Studio и выполнить предыдущий запрос (например, DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)) он не дал ошибку, он работал правильно. - person Peter; 23.09.2010

Чтобы УДАЛИТЬ, не изменяя ссылки, вы должны сначала удалить или иным образом изменить (способом, подходящим для ваших целей) все соответствующие строки в других таблицах.

Чтобы TRUNCATE вы должны удалить ссылки. TRUNCATE — это оператор DDL (сравнимый с CREATE и DROP), а не оператор DML (как INSERT и DELETE), и он не вызывает срабатывания триггеров, будь то явных или связанных со ссылками и другими ограничениями. Из-за этого база данных могла быть переведена в несогласованное состояние, если TRUNCATE был разрешен для таблиц со ссылками. Это было правилом, когда TRUNCATE был расширением стандарта, используемого некоторыми системами, и требуется стандартом, теперь, когда он был добавлен.

person Jon Hanna    schedule 23.09.2010