0

Я хочу удалить строки на дочерней таблице. Я получаю ошибкуСвязаны ли ограничения внешнего ключа на DELETE при удалении ребенка?

В ВЕИТ конфликтный с ссылочным ограничением «FK_Address_UserDataSet». Конфликт произошел в базе данных «XYZ», таблице «dbo.Address», столбец «DataSetId». Заявление было прекращено.

У меня есть структура базы данных с родителем UserDataSet и ребенка Address таблицы (где родитель может иметь любое количество Чайлдс).

Существует ограничение внешнего ключа (упомянутое в ошибке), которое требует, чтобы дочерний DataSetId имел отношение к действию UserDataSet.

Вот таблицы и ограничений скрипты, созданный с MS SQL Server Management Studio 2008 в упрощенном виде:

CREATE TABLE [dbo].[Address](
    [AddressId] [int] IDENTITY(1,1) NOT NULL, 
    [DataSetId] [int] NOT NULL, 
     --other fields 
CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED 
(
    [AddressId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

--- 

CREATE TABLE [dbo].[UserDataSet](
    [DataSetId] [int] IDENTITY(1,1) NOT NULL, 
     --other fields 
CONSTRAINT [PK_UserDataSet] PRIMARY KEY CLUSTERED 
(
    [DataSetId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

---Create the constraint 

ALTER TABLE [dbo].[Address] WITH NOCHECK ADD CONSTRAINT [FK_Address_UserDataSet] FOREIGN KEY([DataSetId]) 
REFERENCES [dbo].[UserDataSet] ([DataSetId]) 
GO 

ALTER TABLE [dbo].[Address] CHECK CONSTRAINT [FK_Address_UserDataSet] 
GO 

Но, как можно удалить ребенок (не родитель) быть проблемой в этой установке?

Может ли быть, что строка для удаления в настоящее время недействительна, вероятно, добавлена, пока ограничение не было (пока) используется), теперь ограничение принудительно выполняется при удалении дочернего элемента с недопустимым внешним ключом?

+1

Не должно быть дочерней строки без действительного родителя. Все еще сделайте повторную проверку в конце. – Kangkan

+1

Я предлагаю вам создавать сценарии создания для обеих таблиц. Восстановите таблицы в тестовой базе данных. Протестируйте, вставив некоторые значения в родительский и дочерний объекты в тестовую базу данных. Попробуйте удалить их и посмотреть, можете ли вы это понять. Если вы не можете понять, что пойдет не так, пожалуйста, перепечатайте сценарии создания таблицы и ваши тестовые вставки/удаления. Проводка создания/вставки/удаления скрипта скажет больше, чем описание тысяч слов :) – mortb

+1

Вы также можете сделать http://SQLFiddle.com/, который показывает нам вашу проблему – mortb

ответ

1

Почему вы добавляете ограничение с помощью NOCHECK?

От MSDN documentation ...

Если вы не хотите, чтобы проверить новую проверку или FOREIGN KEY ограничений против существующих данных, используйте С NOCHECK. Мы не рекомендуем делать это, за исключением редких случаев. Новое ограничение будет оцениваться в все последующие обновления данных. Любые нарушения ограничений, которые подавляются с помощью NOCHECK при добавлении ограничения, могут привести к сбою будущих обновлений , если они обновляют строки данными, которые не соответствуют ограничению .

+0

Хорошая точка, это, скорее всего, корень проблемы. Но что делать теперь, когда я даже не могу удалить? – Marcel

+1

Перед применением ограничения внешнего ключа вам необходимо обеспечить ссылочную целостность. Какой оператор DELETE вы используете? Я бы подумал, что вы можете удалить дочерние записи, у которых есть недопустимый родитель .... –

+0

Оператор delete приходит через Linq to SQL, поэтому я не могу точно сказать прямо сейчас. Но я думал, что удаление детей тоже не проблема - вот в чем заключается этот вопрос ... – Marcel

Смежные вопросы