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;같지만 붙어 있습니다.

답변:


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 테이블이 다른 테이블에 나타납니다. 따라서 delete 문 전에이 관계를 비활성화하고 다시 시도하십시오.

아래는 외래 키를 비활성화하는 것입니다

 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
끔찍한 제안. FK 제약 조건을 비활성화해서는 안됩니다. 이러한 제한 조건은 레코드를 삭제하지 못하게합니다. 그것들을 비활성화하면 데이터베이스에 나쁜 데이터가 생길 것입니다. 최악의 연습은 좋지 않은 연습을 권장합니다.
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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.