2012-12-19 4 views
1

다음 표의 표와 비슷한 여러 외래 키가 하나의 다른 테이블을 가리키고 단일 계단식 배열이 아닌 테이블이있는 거대한 기존 데이터베이스가 있습니다.ON DELETE CASCADE (충돌 참조 제약 조건)을 사용하지 않고 삭제하는 방법

create table Users (
    Id int primary key identity, 
    Name varchar(max) 
) 

create table Products (
    Id int primary key identity, 
    Name varchar(max), 
    CreatedBy int foreign key references Users(Id), 
    UpdatedBy int foreign key references Users(Id) 
) 

insert into Users values('Bar') 
insert into Users values('Baz') 
insert into Products values('Foo', 1, 2) 

나는 이전 데이터의 일부를 삭제 할 수 있어야하지만, 물론 참조 예외가 발생합니다 :

delete from Users where Name='Bar' 

DELETE 문 참조 제약 조건 "FK__Products__Create__와 충돌을 1AD3FDA4 ". 충돌은 데이터베이스 "Foo", 테이블 "dbo.Products", 열 'CreatedBy'에서 발생했습니다. 때문에 나는 모든 참조를 predelete 수없는 데이터베이스의 깎아 지른듯한 복잡성


는, 그래서 프로그래밍을 해결하기 위해 설정 폭포와 임시 외국인 키를 추가하기 위해 노력하고있어. 그러나 다른 한 테이블에 여러 외래 키를 가지고이 특정 테이블에 대해,이 두 번째 UpdatedBycycles or multiple cascade paths 결과는 변경 :

alter table Products add foreign key (CreatedBy) references Users(Id) on delete cascade 
alter table Products add foreign key (UpdatedBy) references Users(Id) on delete cascade 

주기를 일으킬 수 테이블 '제품'에 FOREIGN KEY 제약 조건 'FK__Products__Update__1DB06A4F을'소개 또는 여러 개의 계단식 경로. NO DELETE NO ACTION 또는 UP UP NO NO ACTION을 지정하거나 다른 FOREIGN KEY 제약 조건을 수정하십시오.


중 하나를 어떻게 든 주변의 여러 폭포 경로 문제 또는 기타를 얻어서, 참조 무결성을 유지하면서

가 어떻게 delete from Users where 작업을 할 수 ?

+0

다음을 고려하십시오. 'ID = 3'인 사용자를 삭제하고 싶습니다. 이 사용자가 생성하고'ID = 5 '로 사용자가 업데이트 한 제품이 있습니다. 사용자 '3'을 삭제할 때 캐스케이드의 일부로 해당 제품을 삭제한다고 가정하면 'ID = 5'로 업데이트 된 모든 제품을 쿼리해야합니다. 당신은 하나의 제품을 놓칠 것입니다! 또는 제품을 보관하고'createdBy'를'NULL'로 설정하여 중요한 정보를 놓치지 않도록 할 수 있습니다. 하지만 캐스케이드 삭제가 아닙니다. 해당 사용자를 정말로 삭제하고 더 나은 옵션이 없는지 스스로에게 물어볼 필요가 있습니다. –

답변

1

개인적으로 나는 이것을 수행하지 않을 것입니다 (참조 된 모든 데이터를 사전 삭제하고 무결성을 수동으로 검사합니다). 참조 : Can foreign key constraints be temporarily disabled using T-SQL?

인용구 :

-- disable all constraints 
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all" 

는 제약 조건이 비활성화되면 데이터를 삭제하지만, 다시 이후에 다시를 설정하는 기억!

-- enable all constraints 
EXEC sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all" 

또한 저장 프로 시저 sp_msforeachtable가 문서화하고 SQL Server의 향후 릴리스에서 사라질 수 있습니다.

제약 조건을 포괄적으로 사용 중지하지 않으려면 (위의 코드에서 볼 수있는 것처럼) 사용하지 않도록 설정하면됩니다.

모든 크레딧은 kristof's answer입니다. 투표하십시오!

+0

감사합니다. OP 사전 삭제 참조에서 언급했듯이 db는 절대적으로 방대한 양이며 수백 개의 테이블을 단계별 실행하기 위해 의미있는 자원을 투입하는 생산 기능이 아닙니다. 나는 삭제 된 사용자와 관련된 모든 쓰레기가 삭제되고 참조가 필요하지 않도록 모든 제약 조건 검사를 사용하지 않으려 고하지 않았습니다. –

+0

누군가가 정말로이 답변을 괴롭히지 않았습니까? – Codesleuth