Desativar restrições temporariamente (MS SQL)

Eu estou procurando uma maneira de desativar temporariamente todas as restrições do DB (por exemplo, relacionamentos de tabela).

Eu preciso copiar (usando INSERTs) tabelas de um database para outro database. Eu sei que posso conseguir isso executando comandos na ordem apropriada (para não quebrar relacionamentos).

Mas seria mais fácil se eu pudesse desligar temporariamente as restrições de verificação e ligá-las novamente após a conclusão da operação.

Isso é possível?

Você pode desabilitar as restrições FK e CHECK somente no SQL 2005+ . Ver ALTER TABLE

 ALTER TABLE foo NOCHECK CONSTRAINT ALL 

ou

 ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column 

Chaves primárias e restrições exclusivas não podem ser desabilitadas, mas isso deve ser OK se eu entendi corretamente.

 -- 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' --------------------------------------------------------- 

E, se você quiser verificar que você NÃO quebrou seus relacionamentos e introduziu órfãos, uma vez que você tenha rearmado seus cheques, ie

 ALTER TABLE foo CHECK CONSTRAINT ALL 

ou

 ALTER TABLE foo CHECK CONSTRAINT FK_something 

então você pode correr de volta e fazer uma atualização em qualquer coluna marcada da seguinte forma:

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

E quaisquer erros nesse ponto serão causados ​​por falhas no cumprimento de restrições.

Você pode realmente desabilitar todas as restrições do database em um único comando SQL e reativá-las chamando outro comando único. Vejo:

  • Restrições de chave estrangeira podem ser desativadas temporariamente usando o TSQL?

No momento, estou trabalhando com o SQL Server 2005, mas tenho quase certeza de que essa abordagem também funcionou com o SQL 2000

Desativando e ativando todas as foreign keys

 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 

Primeiro, o cursor foreignKeyCursor é declarado como a instrução SELECT que reúne a lista de foreign keys e seus nomes de tabela. Em seguida, o cursor é aberto e a instrução inicial FETCH é executada. Essa instrução FETCH lerá os dados da primeira linha nas variables ​​locais @foreignKeyName e @tableName. Ao fazer um loop através de um cursor, você pode verificar o @@ FETCH_STATUS para um valor de 0, que indica que a busca foi bem sucedida. Isso significa que o loop continuará a avançar para que possa obter cada chave estrangeira sucessiva do conjunto de linhas. @@ FETCH_STATUS está disponível para todos os cursores na conexão. Portanto, se você estiver fazendo um loop através de vários cursores, é importante verificar o valor de @@ FETCH_STATUS na instrução imediatamente após a instrução FETCH. @@ FETCH_STATUS refletirá o status da operação FETCH mais recente na conexão. Valores válidos para @@ FETCH_STATUS são:

0 = FETCH foi bem sucedido
-1 = FETCH não teve sucesso
-2 = a linha que foi buscada está faltando

Dentro do loop, o código cria o comando ALTER TABLE de forma diferente, dependendo se a intenção é desabilitar ou habilitar a restrição de chave estrangeira (usando a palavra-chave CHECK ou NOCHECK). A declaração é impressa como uma mensagem para que seu progresso possa ser observado e, em seguida, a instrução seja executada. Finalmente, quando todas as linhas tiverem sido iteradas, o procedimento armazenado fecha e desaloca o cursor.

Desabilitando Restrições e Triggers da MSDN Magazine