Eu preciso mover um monte (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 ausentes, 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 na Mago.)
Qual é o caminho certo para fazer isso?
Se fossem apenas algumas tabelas, eu retornaria à fonte, criaria um script para a definição da tabela (com todos os índices, etc.) e depois 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 criar um script da fonte, incluindo dados, mas um script de linha de 72m simplesmente não parece uma boa idéia!
Respostas:
Criar um 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.
fonte
Na verdade, fizemos isso usando muitos scripts manuais em conjunto com o assistente de Importação, mas nesta manhã encontrei uma resposta melhor, cortesia do artigo do blog de Tibor Karaszi .
Parte de nossa frustração aqui foi que o "Assistente de Importação / Exportação DTS" do SQL 2000 torna isso quase trivialmente fácil, selecionando "Copiar objetos e dados":
Essa terceira opção é a que contém a capacidade de incluir índices / gatilhos, etc:
Esta opção foi REMOVIDA no Assistente de Importação do SQL 2005/2008 . Por quê? Nenhuma idéia:
Em 2005/2008, você aparentemente precisa criar manualmente um pacote SSIS no BIDS e usar a tarefa Transferir objetos do SQL Server , que contém todas as mesmas opções do assistente de 2000:
fonte
Eu consideraria criar um script para a tabela ou usar ferramentas 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 após carregar os dados.
Depende do seu nível de conforto com o SSIS (resposta de Mrdenny) ou se você prefere SQL bruto.
fonte
Eu acrescentaria à resposta do Sr. Denny: escreva o esquema das tabelas e use o BCP para mover os dados. Se você não estiver familiarizado com o SSIS, será fácil usar o BCP e os lotes. Para milhões de linhas, nada supera o BCP (inserção em massa) :).
fonte
Sou eu quem está completamente desconfortável com o SSIS.
Quando as tabelas de origem não possuem colunas de identidade
Agora o T-SQL para gerar as instruções Select * em ...
Isso gera uma linha para cada tabela copiar como
Caso as tabelas contenham colunas de identidade, escrevo as tabelas, incluindo a propriedade de identidade e as chaves primárias.
Eu não uso a inserção em ... selecione ... usando um servidor vinculado nesse caso, pois essa não é uma técnica em massa. Estou trabalhando em alguns scripts do PowerShell semelhantes a [esta questão 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.
fonte
Você pode usar ferramentas de comparação que comparam dados e esquemas de banco de dados e primeiro sincronize 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 o ApexSQL Diff e o ApexSQL Data Diff para isso, mas existem outras ferramentas semelhantes.
A coisa boa 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 houver vários shows) e executá-lo.
Como scripts grandes não podem ser abertos no SQL Server Management Studio, eu uso sqlcmd ou osql
fonte
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 novamente nas tabelas.
Este é um método bcp muito rápido, pois usa o modo nativo.
fonte