web-dev-qa-db-ja.com

外部キーを持つテーブルを切り捨てる方法はありますか?

外部キーを持つテーブルを切り捨てる方法はありますか?削除と再シードには時間がかかりすぎる場合があります。キーの削除と再作成は唯一の方法ですか?もしそうなら、これを行うツールはありますか?

3
IvanP

いいえ、キーを削除して再作成するか、削除して再シードするまで待つ必要があります。外部キーを一時的に無効にすると、削除が速くなりますが、それでも切り捨ては許可されません。

ALTER TABLE [dbo].[tablename] NOCHECK CONSTRAINT ALL;

-- delete, reseed, etc.

ALTER TABLE [dbo].[tablename] WITH CHECK CHECK CONSTRAINT ALL;

ターゲットにする必要のあるテーブルに応じて、メタデータテーブルから動的SQLを構築することで、これを非常に簡単に自動化できます。上記は単なるサンプルであり、単一のテーブルに対してどのように実行されるかを示しています。たとえば、これは、外部キーのターゲットであり、IDENTITY列を持つ各テーブルに対してこれを行います。

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'SET NOCOUNT ON;';

;WITH s(t) AS
 (
   SELECT 
     QUOTENAME(OBJECT_SCHEMA_NAME(referenced_object_id)) 
     + '.' + QUOTENAME(OBJECT_NAME(referenced_object_id))
  FROM sys.foreign_keys AS k
  WHERE EXISTS 
  (
    SELECT 1 FROM sys.identity_columns 
    WHERE [object_id] = k.referenced_object_id
  )
  GROUP BY referenced_object_id
)
SELECT @sql = @sql + N'
  ALTER TABLE ' + t + ' NOCHECK CONSTRAINT ALL;
  DELETE ' + t + ';
  DBCC CHECKIDENT(''' + t + ''', RESEED, 0) WITH NO_INFOMSGS;
  ALTER TABLE ' + t + 'WITH CHECK CHECK CONSTRAINT ALL;'
FROM s;

PRINT @sql;
-- EXEC sp_executesql @sql;

出力が切り捨てられる可能性がありますが、これはPRINT(8K)の制限にすぎません-実際のコマンドは完了しています。

PSこれはSQL Server 2005以降を想定しています。質問の一部としてバージョンを指定するのに常に役立ちます(通常はタグを使用)。

9
Aaron Bertrand