Eu preciso mover um monte (mais de 100) de tabelas grandes (milhões de linhas) de um banco de dados SQL2008 para outro.
Originalmente, usei apenas o Assistente de Importação/Exportação, mas todas as tabelas de destino estavam sem chaves primárias e estrangeiras, índices, restrições, gatilhos etc. (As colunas de identidade também foram convertidas em INTs simples, mas acho que perdi uma caixa de seleção no bruxo.)
Qual é a maneira certa de fazer isso?
Se fossem apenas algumas tabelas, eu voltaria para a fonte, executaria o script da definição da tabela (com todos os índices, etc.) e executaria as partes de criação de índice do script no destino. Mas com tantas tabelas, isso parece impraticável.
Se não houvesse tantos dados, eu poderia usar o assistente "Criar scripts..." para fazer o script da fonte, incluindo dados, mas um script de 72m de linha simplesmente não parece uma boa ideia!
Fazer o script das tabelas e usar o SSIS para transferir os dados seria a maneira mais confiável e eficaz de mover os dados para o novo banco de dados.
Na verdade, fizemos isso usando muitos scripts manuais em conjunto com o assistente de importação, mas esta manhã encontrei uma resposta melhor, cortesia do artigo do blog de Tibor Karaszi .
Parte de nossa frustração aqui foi que o SQL 2000 "DTS Import/Export Wizard" torna isso quase trivialmente fácil selecionando "Copy Objects and Data":
Esta terceira opção é a que contém a capacidade de incluir índices/gatilhos, etc:
Esta opção foi REMOVIDA do SQL 2005/2008 Import Wizard. Por quê? Nenhuma idéia:
Em 2005/2008, você aparentemente tem que criar manualmente um pacote SSIS no BIDS e usar a Tarefa Transferir Objetos do SQL Server , que contém todas as mesmas opções que estavam no assistente 2000:
Eu consideraria fazer um script da tabela ou usar uma ferramenta de comparação (por exemplo, Red Gate) para gerar as tabelas no banco de dados de destino. Sem índices ou restrições ainda.
Então eu consideraria restaurar o banco de dados com um nome diferente no mesmo servidor e fazer
.. para cada tabela, com SET IDENTITY INSERT ON se necessário
Então eu adicionaria índices e restrições depois de carregar os dados.
Depende do seu nível de conforto com o SSIS (resposta do mrdenny) ou se você preferir SQL bruto.
Eu acrescentaria à resposta do Sr. Denny: Script do esquema de tabelas e use o BCP para mover os dados. Se você não estiver familiarizado com o SSIS, usar BCP e lotes deve ser fácil de fazer. Para milhões de linhas, nada supera o BCP (inserção em massa) :).
Eu sou o único que está completamente desconfortável com o SSIS.
Quando as tabelas de origem não têm colunas de identidade
Agora o T-SQL para gerar as instruções Select * into ...
Isso gera uma linha para cada tabela para copiar como
Caso as tabelas contenham colunas de identidade, eu crio scripts nas tabelas incluindo propriedade de identidade e chaves primárias.
Eu não uso insert into ... select ... usando um servidor vinculado neste caso, pois essa não é uma técnica em massa. Estou trabalhando em alguns scripts do PowerShell semelhantes a [esta pergunta SO 1 , mas ainda estou trabalhando no tratamento de erros. Tabelas realmente grandes podem causar erros de falta de memória, pois uma tabela inteira é carregada na memória, antes de ser enviada via SQLBulkCopy para o banco de dados.
A recriação de índices etc. é semelhante ao caso acima. Desta vez posso pular a recriação das chaves primárias.
Você pode usar ferramentas de comparação que comparam esquemas e dados de banco de dados e primeiro sincronizar um esquema de banco de dados em branco com o banco de dados original para criar todas as tabelas.
Em seguida, sincronize os dados do banco de dados original com o novo (todas as tabelas estão lá, mas estão todas vazias) para inserir os registros nas tabelas
Eu uso ApexSQL Diff e ApexSQL Data Diff para isso, mas existem outras ferramentas semelhantes.
O bom desse processo é que você não precisa sincronizar os bancos de dados usando a ferramenta, pois isso pode ser bastante doloroso para milhões de linhas.
Você pode simplesmente criar um script INSERT INTO SQL (não se surpreenda se forem vários shows) e executá-lo.
Como scripts tão grandes não podem ser abertos no SQL Server Management Studio, eu uso sqlcmd ou osql
Como @mrdenny mencionou -
Em vez de usar o SSIS, use o BCP para inserir dados
bcp os dados usando o script abaixo. defina o SSMS no modo de texto e copie a saída gerada pelo script abaixo em um arquivo bat.
Execute o arquivo bat que irá gerar os arquivos .dat na pasta que você especificou.
Execute o script abaixo no
Execute a saída usando o SSMS para inserir dados de volta nas tabelas.
Este é um método bcp muito rápido, pois usa o modo nativo.