모든 테이블에서 모든 제약 조건을 어떻게 삭제합니까?


30

SQL Server 데이터베이스의 모든 테이블에서 모든 기본 제약 조건, 검사 제약 조건, 고유 제약 조건, 기본 키 및 외래 키를 삭제하고 싶습니다. 에서 모든 구속 조건 이름을 얻는 방법을 알고 sys.objects있지만 어떻게 ALTER TABLE부품을 채우 나요?


호기심에서 그러한 요청의 맥락은 무엇입니까? 기능적 종속성이 어떻게 해결되는지 궁금합니다 (예 : 인덱싱 된 뷰, FK의 캐스케이드 이벤트 및 IGNORE_DUP_KEY = ON 인 UQ).
Solomon Rutzky

3
@srutzky Stack Overflow에서 요청 했지만 여기에 더 깨끗하고 정식 버전을 만들기로 결정했습니다. 어쨌든 그것은 일반적으로 요청이며, 종종 데이터베이스 정리 (시작, 실수로 마스터에 넣은 오브젝트 정리 등)를 수행하는 더 큰 작업의 일부입니다. 제약 조건을 삭제하여 이러한 기능 종속성이 영향을받는 것을 보지 못합니다. 실제로 대부분의 경우 더 큰 그림이 테이블을 자르거나 삭제한다고 생각합니다. 제약 조건을 먼저 삭제하면 가능합니다.
Aaron Bertrand

답변:


36

sys.tables.object_id = sys.objects.parent_object_id해당 객체 유형 에 가입하면이 정보를 쉽게 얻을 수 있습니다 .

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + N'
  ALTER TABLE ' + QUOTENAME(s.name) + N'.'
  + QUOTENAME(t.name) + N' DROP CONSTRAINT '
  + QUOTENAME(c.name) + ';'
FROM sys.objects AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
INNER JOIN sys.schemas AS s 
ON t.[schema_id] = s.[schema_id]
WHERE c.[type] IN ('D','C','F','PK','UQ')
ORDER BY c.[type];

PRINT @sql;
--EXEC sys.sp_executesql @sql;

PRINT제한 사항 이 많은 경우 8K로 제한되므로 전체 스크립트를 표시하지 않을 수 있습니다. 이러한 경우 실행 전에 스크립트의 유효성을 검사하는 다른 방법 은 이 팁 을 참조하십시오 .

출력에 만족하면의 주석을 해제하십시오 EXEC.


3
기본 키보다 외래 키 제약 조건을 삭제해야 할 수도 있습니다. ORDER BY (CASE WHEN c.[type] IN ('PK', 'UQ') THEN 1 ELSE 0 END)
Daniel Hutmacher

1
@Daniel 좋은 점, ORDER BY 유형은 SQL Server가 새로운 제약 유형을 도입 할 때까지 충분할 것입니다.
Aaron Bertrand

6

나는 받아 들인 대답으로 시작하여 동적 SQL에서 전체 SQL 문을 작성하는 대신 while 루프를 사용하도록 구조를 수정했습니다. 나는 여러 가지 이유로 이것을 더 좋아합니다.

쿼리는 큰 @sql 변수에 저장되지 않습니다. 이 구현은 출력에서 ​​로깅 목적으로 삭제 된 각 제한 조건에 대해 인쇄를 허용합니다. 단위 테스트에서 실행 속도가 약간 빨라졌습니다.

Set NoCount ON

Declare @schemaName varchar(200)
set @schemaName=''
Declare @constraintName varchar(200)
set @constraintName=''
Declare @tableName varchar(200)
set @tableName=''

While exists
(   
    SELECT c.name
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.[type] IN ('D','C','F','PK','UQ')
    and t.[name] NOT IN ('__RefactorLog', 'sysdiagrams')
    and c.name > @constraintName
)

Begin   
    -- First get the Constraint
    SELECT 
        @constraintName=min(c.name)
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.[type] IN ('D','C','F','PK','UQ')
    and t.[name] NOT IN ('__RefactorLog', 'sysdiagrams')
    and c.name > @constraintName

    -- Then select the Table and Schema associated to the current constraint
    SELECT 
        @tableName = t.name,
        @schemaName = s.name
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.name = @constraintName

    -- Then Print to the output and drop the constraint
    Print 'Dropping constraint ' + @constraintName + '...'
    Exec('ALTER TABLE [' + @schemaName + N'].[' + @tableName + N'] DROP CONSTRAINT [' + @constraintName + ']')
End

Set NoCount OFF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.