2012-11-20 2 views
0

방금 ​​레거시 데이터베이스에 약 80 개의 "누락 된"외래 키가 추가되었으며 FK 제약 조건으로 인해 테이블을 삭제할 때 데이터베이스 재 작성 스크립트가 실패합니다. 전략은 항상 테이블을 자연 순서대로 놓는 것이 었습니다. 그리고 이것은 지금까지 성공했습니다. 나는이 방법을 유지하지 않으려는이 같은 모든 FK 제약 조건을 비활성화 시도 :sp_msforeachtable을 사용하여 FK 제약 조건을 해제하면 FK 오류가 발생합니다.

USE MYDB; 
GO 

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all" 
GO 

DROP TABLE [dbo].[Table1] 
DROP TABLE [dbo].[Table2] 
DROP TABLE [dbo].[Table3] 
... 

exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all" 
GO 

문제는 아직도 얻고있다 오류 :

메시지 3726, 수준 16, 상태 1 , 줄 17 개체를 삭제할 수 없습니다 'dbo.Table1'FOREIGN KEY 제약 조건에 의해 참조되기 때문에. 메시지 수준 16, 상태 1, 줄 18 3726 FOREIGN KEY 제약 조건에 의해 참조 된 때문에 'dbo.Table2' 개체를 삭제할 수 없습니다.

누구든지 내가 뭘 잘못하고 있다고 제안 할 수 있습니까? 내가 R2 편집

윈도우 7에 SQL Server 2008을 사용하고 있습니다 : 내가 순환 참조가 나타났습니다, 즉 표는 표 2에 FK, 그 반대가 있지만 그럼에도 불구하고 ....

+0

FK 제약 조건을 비활성화하면 충분하지 않습니다. 이 오류를 피하기 위해 실제로이를 h 제해야합니다. –

+0

확인해 주셔서 감사합니다. 테이블을 삭제하기 전에 필요한 작업을 수행하는 sp_dropconstraint 저장 프로 시저를 복사했습니다. 내가 정말로 원하는 것은 드롭 테이블 명령을 그들이 작동하는 순서대로 구성 할 수있는 코드입니다. 순환 참조가 문제가 될 수 있지만 ... – Oversteer

답변

1

drop table 명령을 실행하기 전에 모든 제한 조건을 제거 할 수 있습니다. 스크립트 상단에서 이와 같은 것이 작동해야합니다.

declare @newLine as varchar(1) = char(13); 
    declare @sqlCmd as varchar(max) = ''; 

    SELECT @sqlCmd = @sqlCmd + 'alter table ' + OBJECT_NAME(parent_object_id) + ' drop constraint ' + OBJECT_NAME(OBJECT_ID) + ';' + @newLine 
    FROM sys.objects 
    WHERE type_desc LIKE '%CONSTRAINT' 
     and OBJECT_NAME(parent_object_id) not in ('list','of','tables','to','ignore') 
    order by case when left(OBJECT_NAME(OBJECT_ID),2) = 'PK' then 1 else 0 end 
    exec (@sqlCmd) 
    go 
+0

문제는 대답에서 코드를 시도한 다음 "제약 조건 'PK_xxxxx'이 'Tablexxx'테이블, 외래 키 제약 조건 'XPKxxxxxxxxx'에 의해 참조되는 것입니다." " ,. 내가하는 일이 중요하지 않은 것처럼 보입니다. 뭔가 실패합니다. 제약 조건 때문에 테이블을 삭제할 수 없으며 테이블에서 참조하기 때문에 제약 조건을 삭제할 수 없습니다. 그것은 윈 - 윈 상황처럼 보인다. 나는 스크립트를 안정적으로 실행하려고 최선을 다했습니다. – Oversteer

+0

오류는 기본 키 제약 조건으로 인해 발생합니다. 마지막으로 SQL 명령을 변경했습니다. 그게 도움이되는지 알려주세요 – Durus

+0

고마워요. 이것은 나를 위해 안정적으로 작동합니다. LIKE 'FOREIGN_KEY_CONSTRAINT'을 (를) 사용하고 있습니다. – Oversteer