私は一時的にすべてのDBの制約(例えばテーブルの関係)を無効にする方法を探しています。
あるDBのテーブルを別のDBに(INSERTを使って)コピーする必要があります。 (関係を壊さないように)適切な順序でコマンドを実行することでこれを達成できることを私は知っています。
しかし、チェック制約を一時的にオフにして、操作の終了後にそれをオンに戻すことができれば、もっと簡単になるでしょう。
これは可能ですか?
FKとCHECKの制約を無効にすることができます sQL 2005以降のみ。 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マガジンから制約とトリガを無効にする