226

すべてのDBの制約(テーブルの関係など)を一時的にオフにする方法を探しています。

あるDBのテーブルを別のDBに(INSERTを使用して)コピーする必要があります。コマンドを適切な順序で実行することで(関係を壊さないように)それを達成できることを私は知っています。

ただし、制約のチェックを一時的にオフにして、操作の終了後にオンに戻すことができれば、より簡単になります。

これは可能ですか?

4

5 に答える 5

282
-- 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 in the database:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

-- Re-enable constraints for all tables in the database:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
---------------------------------------------------------
于 2014-10-24T16:30:45.313 に答える
232

FKおよびCHECK制約は、SQL2005以降でのみ無効にできますALTERTABLEを参照してください

ALTER TABLE foo NOCHECK CONSTRAINT ALL

また

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

主キーと一意の制約を無効にすることはできませんが、正しく理解していれば、これで問題ありません。

于 2009-04-10T09:36:55.737 に答える
56

そして、あなたがあなたの関係を壊して孤児を紹介したことがないことを確認したいなら、あなたがあなたの小切手を再び武装させたら、すなわち

ALTER TABLE foo CHECK CONSTRAINT ALL

また

ALTER TABLE foo CHECK CONSTRAINT FK_something

次に、戻って、次のようにチェックされた列に対して更新を行うことができます。

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

そして、その時点でのエラーは、制約を満たしていないことが原因になります。

于 2009-04-10T15:00:14.243 に答える
16

実際には、単一のSQLコマンドですべてのデータベース制約を無効にし、別の単一コマンドを呼び出してそれらを再度有効にすることができます。見る:

私は現在SQLServer2005を使用していますが、このアプローチはSQL2000でも機能することはほぼ間違いありません。

于 2009-04-21T15:13:54.350 に答える
0

すべての外部キーの無効化と有効化

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キーワードを使用)に応じて、ALTERTABLEコマンドを異なる方法で作成します。次に、ステートメントがメッセージとして出力されるため、進行状況を確認して、ステートメントを実行できます。最後に、すべての行が繰り返されると、ストアドプロシージャが閉じて、カーソルの割り当てが解除されます。

MSDNMagazineの制約とトリガーの無効化を参照してください。

于 2009-11-12T07:56:42.860 に答える