programing

제약 조건을 일시적으로 해제합니다(MS SQL).

showcode 2023. 5. 20. 11:00
반응형

제약 조건을 일시적으로 해제합니다(MS SQL).

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

한 DB의 테이블을 다른 DB로 복사(INSERT 사용)해야 합니다.관계를 끊지 않도록 적절한 순서로 명령을 실행하면 이를 달성할 수 있습니다.

하지만 제약 조건 확인을 일시적으로 껐다가 수술이 끝나면 다시 켤 수 있다면 더 쉬울 것 같습니다.

이것이 가능합니까?

-- 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 in the database:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

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

FK 및 CHECK 제약 조건을 비활성화할 수 있습니다. SQL 2005+에서만 사용 가능 ALTER TABLE 참조

ALTER TABLE foo NOCHECK CONSTRAINT ALL

또는

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

기본 키와 고유한 제약 조건을 사용하지 않도록 설정할 수는 없지만, 사용자를 올바르게 이해했다면 문제가 없을 것입니다.

그리고 만약 당신이 당신의 관계를 깨뜨리고 고아들을 소개하지 않았다는 것을 증명하고 싶다면, 일단 당신이 당신의 수표를 다시 무장시킨 후에.

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

먼저, 외부 키 커서는 외부 키 목록과 해당 테이블 이름을 수집하는 SELECT 문으로 선언됩니다.그런 다음 커서가 열리고 초기 FETCH 문이 실행됩니다.이 FETCH 문은 첫 번째 행의 데이터를 로컬 변수 @foreignKeyName 및 @tableName으로 읽습니다.커서를 루프할 때 @@FETCH_STATUS 값 0을 확인할 수 있으며, 이는 가져오기가 성공했음을 나타냅니다.즉, 루프가 계속 앞으로 이동하여 행 집합에서 각 연속 외래 키를 가져올 수 있습니다.@@FETCH_STATUS는 연결의 모든 커서에서 사용할 수 있습니다.따라서 여러 커서를 통과하는 경우 FETCH 문 바로 뒤에 있는 문에서 @@FETCH_STATUS 값을 확인하는 것이 중요합니다.@@FETCH_STATUS는 연결에서 가장 최근의 FETH 작업에 대한 상태를 반영합니다.@@FETCH_STATUS의 유효한 값은 다음과 같습니다.

= 성공 = FETCH 공
= -1 = FETCH가 실패했습니다.
= 되었습니다. -2 = 누락되었습니다.

루프 내에서 코드는 외부 키 제약 조건을 비활성화하거나 활성화할 것인지(CHECK 또는 NOCHECK 키워드 사용)에 따라 ALTER TABLE 명령을 다르게 구성합니다.그런 다음 진행 상황을 관찰할 수 있도록 문이 메시지로 인쇄된 다음 문이 실행됩니다.마지막으로 모든 행이 반복되면 저장 프로시저가 닫히고 커서의 할당이 취소됩니다.

MSDN 매거진에서 제약 조건 및 트리거 사용 안 함을 참조하십시오.

언급URL : https://stackoverflow.com/questions/737115/turn-off-constraints-temporarily-ms-sql

반응형