모든 DB 제약 조건 (예 : 테이블 관계)을 일시적으로 해제하는 방법을 찾고 있습니다.
하나의 DB 테이블을 다른 DB에 복사 (INSERT 사용)해야합니다. 적절한 순서로 명령을 실행하여 (관계를 깨지 않도록) 달성 할 수 있다는 것을 알고 있습니다.
그러나 검사 제약 조건을 일시적으로 해제하고 작업 완료 후 다시 설정하면 더 쉬울 것입니다.
이게 가능해?
답변
SQL 2005+에서만 FK 및 CHECK 제약 조건을 비활성화 할 수 있습니다 . ALTER TABLE 참조
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
먼저 foreignKeyCursor 커서는 외래 키 목록과 테이블 이름을 수집하는 SELECT 문으로 선언됩니다. 다음으로 커서가 열리고 초기 FETCH 문이 실행됩니다. 이 FETCH 문은 첫 번째 행의 데이터를 로컬 변수 @foreignKeyName 및 @tableName으로 읽습니다. 커서를 반복 할 때 @@ FETCH_STATUS에서 0 값을 확인할 수 있으며 이는 페치가 성공했음을 나타냅니다. 이는 루프가 계속 앞으로 이동하여 행 세트에서 각 연속 외래 키를 가져올 수 있음을 의미합니다. @@ FETCH_STATUS는 연결의 모든 커서에 사용 가능합니다. 따라서 여러 커서를 반복하는 경우 FETCH 문 바로 다음 명령문에서 @@ FETCH_STATUS 값을 확인해야합니다. @@ FETCH_STATUS는 연결에서 가장 최근의 FETCH 작업 상태를 반영합니다. @@ FETCH_STATUS의 유효한 값은 다음과 같습니다.
0 = FETCH 성공
-1 = FETCH 실패
-2 = 페치 된 행이 누락 됨루프 내에서 코드는 외래 키 제약 조건 (CHECK 또는 NOCHECK 키워드 사용)의 사용 여부에 따라 ALTER TABLE 명령을 다르게 작성합니다. 그러면 명령문이 메시지로 인쇄되어 진행 상황을 관찰 한 다음 명령문이 실행됩니다. 마지막으로 모든 행이 반복되면 저장 프로 시저가 커서를 닫고 할당을 해제합니다.
MSDN Magazine의 제약 조건 및 트리거 비활성화를 참조하십시오.
답변
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)