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?
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.
-- 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'
---------------------------------------------------------
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.
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.
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 manquanteDans 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