DELETE语句与REFERENCE约束冲突


11

我正在尝试删除所有用户,但出现错误:

Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_M02ArticlePersons_M06Persons". The conflict occurred in database "workdemo.no", table "dbo.M02ArticlePersons", column 'M06PersonId'.
The statement has been terminated.

查询:

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
WHERE ID > '13'
GO

似乎我需要使用,on delete cascade;但卡住了。

Answers:


18

您不需要使用on delete级联。某人(架构设计作者)已确保您不能删除文章仍引用的人。它成功了,您只是试图做到这一点,而被阻止了,这对设计师来说是个荣誉。

现在,与设计架构并了解约束的人员进行交谈,并询问他如何正确地删除要尝试删除的记录,并以正确的顺序进行并采取适当的预防措施以保持数据库的一致性。


9

您在这里有两个实际选择,您可以在表上禁用约束。这通常不是一个好主意,因为如果您弄乱了与其他表相关的数据,但又不了解架构的全部范围,并且可能适合您的目的,那么最终可能会导致不良的数据状况:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] NOCHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

记住在删除后重新打开约束

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH CHECK CHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

第二种选择是使用ON DELETE CASCADE选项删除并重新添加约束,方法是:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] DROP CONSTRAINT [FK_M02ArticlePersons_M06Persons]

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH NOCHECK ADD CONSTRAINT [FK_M02ArticlePersons_M06Persons] FOREIGN KEY(M06PersonId)
REFERENCES <parent table here> (<parent column here>)
ON DELETE CASCADE

根据您的FK名称,看起来您的父表是M02ArticlePersons,而父列是M06Persons。

如果您未编写此架构,请尝试考虑为什么会出现约束,并理解以这种方式违反约束可能会产生意想不到的副作用。


2

列M06PersonId的dbo.M02ArticlePersons表在另一个表中引用。因此,在删除语句之前,请禁用此关系,然后重试

下面是禁用外键

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
  WHERE ID > '13'
GO

这是为了启用它

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

希望这会起作用


2
可怕的建议。除非您是高级dba,否则切勿禁用FK约束(在这种情况下,您无需在上面写问题)。这些限制是为了防止您删除记录。禁用它们willy nilly会给您数据库中的错误数据。您建议的是最糟糕的做法,而不是好的做法。
HLGEM

1

也有另一个手动选项:

您可以转到子表并删除由父键引用的子行。然后,您可以删除父行。本质上,这就是级联删除的作用。这样,您不必删除/重新创建/更改约束。


1

这个小代码将对您要从中删除记录的任何表有所帮助。它也照顾参照完整性...

下面的代码将生成DELETE语句。只需指定schema.table_Name

Declare @sql1 varchar(max)
      , @ptn1 varchar(200)
      , @ctn1 varchar(200)
      , @ptn2 varchar(200)
      , @ctn2 varchar(200)
--
SET @ptn1 = ''
--
SET @ctn1 = ''
--
SET @ptn2 = ''
--
SET @ctn2 = ''
--
SELECT @sql1 = case when (@ptn1 <> OBJECT_NAME (f.referenced_object_id)) then
                         COALESCE( @sql1 + char(10), '') + 'DELETE' + char(10) + ' ' + OBJECT_NAME (f.referenced_object_id) + ' FROM ' + OBJECT_NAME(f.parent_object_id) + ', '+OBJECT_NAME (f.referenced_object_id) + char(10) +' WHERE ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    else
                         @sql1 + ' AND ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    end + char(10)
     , @ptn1 = OBJECT_NAME (f.referenced_object_id)
     , @ptn2  = object_name(f.parent_object_id)
FROM   sys.foreign_keys AS f
       INNER JOIN
       sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
WHERE  f.parent_object_id = OBJECT_ID('dbo.M06Persons'); -- CHANGE here schema.table_name
--
print  '--Table Depended on ' + @ptn2 + char(10) + @sql1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.