web-dev-qa-db-fra.com

Désactiver temporairement les contraintes (MS SQL)

Je cherche un moyen de désactiver temporairement toutes les contraintes de la base de données (par exemple, les relations entre les tables).

Je dois copier (à l'aide d'INSERT) les tables d'un DB dans un autre DB. Je sais que je peux y parvenir en exécutant des commandes dans le bon ordre (pour ne pas rompre les relations).

Mais ce serait plus facile si je pouvais désactiver temporairement les contraintes de vérification et les réactiver une fois l'opération terminée.

Est-ce possible?

197
Maciej

Vous pouvez désactiver les contraintes FK et CHECK uniquement dans SQL 2005+. Voir ALTER TABLE

ALTER TABLE foo NOCHECK CONSTRAINT ALL

ou

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

Les clés primaires et les contraintes uniques ne peuvent pas être désactivées, mais cela devrait être correct si je vous ai bien compris.

207
gbn
-- 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'
---------------------------------------------------------
203
Donal

Et, si vous voulez vérifier que vous n’AVEZ PAS brisé vos relations et introduit des orphelins, une fois que vous avez ré-armé vos chèques, c’est-à-dire.

ALTER TABLE foo CHECK CONSTRAINT ALL

ou

ALTER TABLE foo CHECK CONSTRAINT FK_something

alors vous pouvez revenir en arrière et faire une mise à jour contre toutes les colonnes vérifiées comme ceci:

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

Et toutes les erreurs à ce stade seront dues au non-respect des contraintes.

57

En fait, vous pouvez désactiver toutes les contraintes de la base de données dans une seule commande SQL et les réactiver en appelant une autre commande unique. Voir:

Je travaille actuellement avec SQL Server 2005, mais je suis presque sûr que cette approche a également fonctionné avec SQL 2000.

16
kristof

Désactiver et activer toutes les clés étrangères

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

Tout d'abord, le curseur foreignKeyCursor est déclaré en tant qu'instruction SELECT qui rassemble la liste des clés étrangères et leurs noms de table. Ensuite, le curseur est ouvert et l'instruction FETCH initiale est exécutée. Cette instruction FETCH lira les données de la première ligne dans les variables locales @foreignKeyName et @tableName. Lorsque vous parcourez un curseur, vous pouvez vérifier la valeur 0 de @@ FETCH_STATUS, ce qui indique que la récupération a abouti. Cela signifie que la boucle continuera à avancer pour pouvoir extraire chaque clé étrangère successive du jeu de lignes. @@ FETCH_STATUS est disponible pour tous les curseurs de la connexion. Ainsi, si vous parcourez plusieurs curseurs, il est important de vérifier la valeur de @@ FETCH_STATUS dans l'instruction qui suit immédiatement l'instruction FETCH. @@ FETCH_STATUS reflètera le statut de la dernière opération FETCH sur la connexion. Les valeurs valides pour @@ FETCH_STATUS sont:

0 = FETCH a réussi
- 1 = FETCH a échoué
- 2 = la ligne extraite est manquante

Dans la boucle, le code construit la commande ALTER TABLE différemment selon que l'intention est de désactiver ou d'activer la contrainte de clé étrangère (à l'aide du mot clé CHECK ou NOCHECK). L'instruction est ensuite imprimée sous forme de message afin que sa progression puisse être observée, puis l'instruction est exécutée. Enfin, lorsque toutes les lignes ont été itérées, la procédure stockée se ferme et libère le curseur.

voir Désactivation des contraintes et des déclencheurs de MSDN Magazine

2
0x49D1