Desabilitar e habilitar restrições de chave estrangeira são suportadas no SQL Server? Ou é a minha única opção para drop
e depois refazercreate
as restrições?
824
Desabilitar e habilitar restrições de chave estrangeira são suportadas no SQL Server? Ou é a minha única opção para drop
e depois refazercreate
as restrições?
Respostas:
Se você deseja desativar todas as restrições no banco de dados, basta executar este código:
Para ativá-los novamente, execute: (a impressão é opcional, é claro, e está apenas listando as tabelas)
Acho útil ao preencher dados de um banco de dados para outro. É uma abordagem muito melhor do que eliminar restrições. Como você mencionou, é útil ao descartar todos os dados no banco de dados e preenchê-los novamente (digamos, no ambiente de teste).
Se você estiver excluindo todos os dados, poderá achar útil esta solução .
Às vezes, também é útil desativar todos os gatilhos. Você pode ver a solução completa aqui .
fonte
"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Deveria haver apenas um "CHECK" lá?http://www.sqljunkies.com/WebLog/roman/archive/2005/01/30/7037.aspx
fonte
Para desabilitar a restrição, você tem
ALTER
a tabela usando NOCHECKPara permitir que você precise usar o CHECK duplo :
Depois de concluído, se você precisar verificar o status, use este script para listar o status da restrição. Será muito útil:
fonte
sys.sysforeignkeys
msdn.microsoft.com/en-us/library/ms177604.aspxSua melhor opção é DROP e CRIAR restrições de chave estrangeira.
Não encontrei exemplos neste post que funcionariam para mim "como estão", um não funcionaria se chaves estrangeiras fizessem referência a esquemas diferentes, o outro não funcionaria se chaves estrangeiras fizessem referência a várias colunas. Este script considera os dois esquemas múltiplos e as colunas múltiplas por chave estrangeira.
Aqui está o script que gera instruções "ADD CONSTRAINT", para várias colunas as separará por vírgula ( salve essa saída antes de executar as instruções DROP ):
Aqui está o script que gera instruções "DROP CONSTRAINT":
fonte
O padrão SQL-92 permite que uma restrição seja declarada como DEFERRABLE, para que possa ser adiada (implícita ou explicitamente) dentro do escopo de uma transação. Infelizmente, o SQL Server ainda está faltando essa funcionalidade do SQL-92.
Para mim, alterar uma restrição para NOCHECK é semelhante à alteração imediata da estrutura do banco de dados - certamente é necessário eliminar restrições - e algo a ser evitado (por exemplo, os usuários exigem privilégios aumentados).
fonte
Eu concordo com você, Hamlin. Quando você transfere dados usando o SSIS ou quando deseja replicar dados, parece bastante necessário desativar temporariamente ou eliminar restrições de chave estrangeira e depois reativá-las ou recriá-las. Nesses casos, a integridade referencial não é um problema, porque já é mantida no banco de dados de origem. Portanto, você pode ter certeza sobre esse assunto.
fonte
fonte
WITH CHECK CHECK
é quase certamente necessário!Este ponto foi levantado em algumas das respostas e comentários, mas acho que é importante o suficiente para chamá-lo novamente.
A reativação de uma restrição usando o seguinte comando (no
WITH CHECK
) terá algumas desvantagens sérias .Nota: WITH NOCHECK é o padrão para reativar restrições. Eu tenho que me perguntar por que ...
A exibição do sistema sys.foreign_keys fornece alguma visibilidade do problema. Observe que ele possui
is_disabled
umais_not_trusted
coluna e uma .is_disabled
indica se operações futuras de manipulação de dados serão validadas contra a restrição.is_not_trusted
indica se todos os dados atualmente na tabela foram validados com relação à restrição.Suas restrições são confiáveis? Descobrir...
fonte
Primeiro post :)
Para o OP, a solução da kristof funcionará, a menos que haja problemas com grandes problemas de dados e balão de log de transações com grandes exclusões. Além disso, mesmo com o armazenamento do tlog de sobra, uma vez que as exclusões são gravadas no tlog, a operação pode demorar muito para tabelas com centenas de milhões de linhas.
Uso uma série de cursores para truncar e recarregar cópias grandes de um de nossos grandes bancos de dados de produção com frequência. A solução projetada é responsável por vários esquemas, várias colunas de chave estrangeira e, o melhor de tudo, pode ser implementada para uso no SSIS.
Envolve a criação de três tabelas intermediárias (tabelas reais) para abrigar os scripts DROP, CREATE e CHECK FK, criação e inserção desses scripts nas tabelas e, em seguida, percorrer as tabelas e executá-las. O script anexado é composto de quatro partes: 1.) criação e armazenamento dos scripts nas três tabelas temporárias (reais), 2.) execução dos scripts drop FK por meio de um cursor, um por um, 3.) Usando sp_MSforeachtable para truncar todos os tabelas no banco de dados que não sejam nossas três tabelas intermediárias e 4.) execução do create FK e verifique os scripts FK no final do seu pacote ETL SSIS.
Execute a parte de criação de script em uma tarefa Executar SQL no SSIS. Execute a parte "execute Drop FK Scripts" em uma segunda tarefa Executar SQL. Coloque o script de truncamento em uma terceira tarefa Execute SQL e, em seguida, execute quaisquer outros processos ETL necessários antes de anexar os scripts CREATE e CHECK em uma tarefa final Execute SQL (ou dois, se desejado) no final do fluxo de controle.
O armazenamento dos scripts em tabelas reais provou ser inestimável quando a re-aplicação das chaves estrangeiras falha, pois você pode selecionar * em sync_CreateFK, copiar / colar na janela de consulta, executá-los um de cada vez e corrigir os problemas de dados assim que você encontre aqueles que falharam / ainda não estão sendo reaplicados.
Não execute novamente o script se ele falhar sem ter a certeza de aplicar novamente todas as chaves / verificações estrangeiras antes de fazê-lo, ou você provavelmente perderá alguma criação e verificará o script fk quando nossas tabelas de preparação forem descartadas e recriado antes da criação dos scripts a serem executados.
fonte
Encontre a restrição
Execute o SQL gerado por este SQL
Maneira segura.
Nota: Solução adicionada para eliminar a restrição para que a tabela possa ser eliminada ou modificada sem nenhum erro de restrição.
fonte
Clique com o botão direito do mouse no design da tabela e vá para Relacionamentos e escolha a chave estrangeira no painel esquerdo e, no painel direito, defina Aplicar restrição de chave estrangeira como 'Sim' (para habilitar restrições de chave estrangeira) ou 'Não' (para desativá-lo).
fonte
A resposta marcada '905' parece boa, mas não funciona.
A seguir funcionou para mim. Qualquer restrição de chave primária, chave exclusiva ou padrão NÃO pode ser desativada. De fato, se 'sp_helpconstraint' 'mostrar' n / a 'em status_enabled - Significa que NÃO pode ser ativado / desativado.
- Para gerar script para DISABLE
- Para gerar script para ENABLE
fonte
Você realmente deve poder desabilitar as restrições de chave estrangeira da mesma maneira que desabilita temporariamente outras restrições:
Apenas certifique-se de desabilitar a restrição na primeira tabela listada no nome da restrição. Por exemplo, se minha restrição de chave estrangeira fosse FK_LocationsEmployeesLocationIdEmployeeId, eu desejaria usar o seguinte:
mesmo que violar essa restrição produza um erro que não indica necessariamente essa tabela como a origem do conflito.
fonte
Um script para governar todos eles: isso combina comandos truncar e excluir com sp_MSforeachtable, para que você possa evitar soltar e recriar restrições - basta especificar as tabelas que precisam ser excluídas em vez de truncadas e, para meus propósitos, incluí um filtro de esquema extra para o bem medida (testada em 2008r2)
fonte
Você pode desativar temporariamente as restrições em suas tabelas, trabalhar e depois reconstruí-las.
Aqui está uma maneira fácil de fazer isso ...
Desative todos os índices, incluindo as chaves primárias, que desativarão todas as chaves estrangeiras e, em seguida, reative apenas as chaves primárias para que você possa trabalhar com elas ...
[Faça algo, como carregar dados]
Em seguida, reative e reconstrua os índices ...
fonte
@sql
sempre é truncado. :(Eu tenho uma versão mais útil se você estiver interessado. Tirei um pouco de código daqui de um site em que o link não está mais ativo. Eu o modifiquei para permitir uma matriz de tabelas no procedimento armazenado e ele preenche as instruções de descartar, truncar e adicionar antes de executar todas elas. Isso lhe dá controle para decidir quais tabelas precisam ser truncadas.
fonte