web-dev-qa-db-ja.com

すべてのテーブルからすべての制約を削除するにはどうすればよいですか?

SQL Serverデータベースのすべてのテーブルから、すべてのデフォルトの制約、チェック制約、一意の制約、主キー、および外部キーを削除したいと思います。 sys.objectsからすべての制約名を取得する方法を知っていますが、ALTER TABLEパーツにどのように入力しますか?

30
Aaron Bertrand

これらのオブジェクトタイプの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は目を見張るためだけにあります-lotの制約がある場合、スクリプト全体が表示されない場合があります。 8K。これらの場合、スクリプトを実行する前に検証する他の方法については this tip を参照してください。

出力に満足したら、EXECのコメントを外します。

38
Aaron Bertrand

私は受け入れられた答えから始めて、動的SQLで完全なSQLステートメントを構築するのではなく、whileループを使用するように構造を変更しました。いくつかの理由で、私はこれの方が好きです。

クエリは大きな@sql変数に格納されません。この実装では、出力のロギング目的でドロップされた各制約のPrintが可能です。単体テストでは、実行が少し高速に見えました。

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
6
yourbuddypal