문제

모든 DB의 제약 조건 (예 : 테이블 관계)을 일시적으로 끄는 방법을 찾고 있습니다.

하나의 DB 테이블을 다른 DB로 복사해야합니다. 나는 관계를 깨뜨리지 않기 위해 명령을 올바른 순서로 실행함으로써 그것을 달성 할 수 있다는 것을 알고 있습니다.

그러나 제약 조건을 일시적으로 끄고 작업이 끝난 후 다시 켜면 더 쉬울 수 있습니다.

이게 가능해?

도움이 되었습니까?

해결책

FK를 비활성화하고 제약 조건을 확인할 수 있습니다 SQL 2005+에서만. 보다 변경 테이블

ALTER TABLE foo NOCHECK CONSTRAINT ALL

또는

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

기본 키와 고유 한 제약 조건을 비활성화 할 수는 없지만 올바르게 이해하면 괜찮습니다.

다른 팁

-- Disable the constraints on a table called tableName:
ALTER TABLE tableName NOCHECK CONSTRAINT ALL

-- Re-enable the constraints on a table called tableName:
ALTER TABLE tableName WITH CHECK CHECK CONSTRAINT ALL
---------------------------------------------------------

-- Disable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

-- Re-enable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'
---------------------------------------------------------

그리고, 당신이 당신의 관계를 어기지 않고 고아를 소개하지 않았 음을 확인하고 싶다면, 일단 수표를 재구성 한 후에, 즉

ALTER TABLE foo CHECK CONSTRAINT ALL

또는

ALTER TABLE foo CHECK CONSTRAINT FK_something

그런 다음 다시 실행하고 다음과 같은 확인 된 열에 대한 업데이트를 수행 할 수 있습니다.

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

그리고 그 시점의 모든 오류는 제약 조건을 충족하지 못하기 때문입니다.

실제로 단일 SQL 명령에서 모든 데이터베이스 제약 조건을 비활성화하고 다른 단일 명령을 호출 할 수 있습니다. 보다:

현재 SQL Server 2005와 함께 일하고 있지만이 접근 방식은 SQL 2000과도 작동한다고 확신합니다.

모든 외국 키를 비활성화하고 활성화합니다

CREATE PROCEDURE pr_Disable_Triggers_v2
    @disable BIT = 1
AS
    DECLARE @sql VARCHAR(500)
        ,   @tableName VARCHAR(128)
        ,   @tableSchema VARCHAR(128)

    -- List of all tables
    DECLARE triggerCursor CURSOR FOR
        SELECT  t.TABLE_NAME AS TableName
            ,   t.TABLE_SCHEMA AS TableSchema
        FROM    INFORMATION_SCHEMA.TABLES t
        ORDER BY t.TABLE_NAME, t.TABLE_SCHEMA

    OPEN    triggerCursor
    FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
    WHILE ( @@FETCH_STATUS = 0 )
    BEGIN

        SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] '
        IF @disable = 1
            SET @sql = @sql + ' DISABLE TRIGGER ALL'
        ELSE
            SET @sql = @sql + ' ENABLE TRIGGER ALL'

        PRINT 'Executing Statement - ' + @sql
        EXECUTE ( @sql )

        FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

    END

    CLOSE triggerCursor
    DEALLOCATE triggerCursor

먼저, 외국 KeyCursor 커서는 외래 키 목록과 테이블 이름을 모으는 선택 진술로 선언됩니다. 다음으로 커서가 열리고 초기 페치 명령문이 실행됩니다. 이 Fetch 문은 첫 번째 행의 데이터를 로컬 변수 @foreignkeyname 및 @tablename에 읽습니다. 커서를 통해 반복 할 때 @@ fetch_status의 0 값을 확인할 수 있습니다. 이는 Fetch가 성공했음을 나타냅니다. 이는 루프가 계속해서 앞으로 이동하여 각각의 연속적인 외국 키를 행 세트에서 얻을 수 있음을 의미합니다. @@ fetch_status는 연결의 모든 커서에서 사용할 수 있습니다. 따라서 여러 커서를 통해 반복되는 경우 Fetch 문의 바로 다음 문서에서 @@ Fetch_status의 값을 확인하는 것이 중요합니다. @@ fetch_status는 연결에서 가장 최근의 페치 작업 상태를 반영합니다. @@ fetch_status의 유효한 값은 다음과 같습니다.

0 = Fetch가 성공했습니다
-1 = 페치는 실패했습니다
-2 = 가져온 행이 누락되었습니다

루프 내부에서 코드는 의도가 외래 키 제약 조건을 비활성화하거나 활성화하는지 여부에 따라 Alter Table 명령을 다르게 빌드합니다 (점검 또는 NoCheck 키워드 사용). 그런 다음 진술은 메시지로 인쇄되므로 진행 상황이 관찰되고 진술이 실행됩니다. 마지막으로, 모든 행이 반복되면 저장된 절차가 닫히고 커서를 거래합니다.

보다 MSDN 매거진의 제약 및 트리거 비활성화

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top