Questão:
Eu tenho um script com cerca de 45 mil inserções de instruções select. Quando tento executá-lo, recebo uma mensagem de erro informando que fiquei sem memória. Como posso executar esse script?
Contexto:
- Foram adicionados alguns novos campos de dados para que um aplicativo funcione bem com outro aplicativo que o cliente usa.
- Obteve uma planilha de dados do cliente cheia de dados que mapeou os itens de dados atuais para valores para esses novos campos.
- Planilha convertida para inserir instruções.
- Se eu executar apenas algumas das instruções, ele funciona, mas o script inteiro não.
- Não. Não há erros de digitação.
Se houver uma maneira diferente de carregar esses dados, sinta-se à vontade para me castigar e me avisar.
sql-server
sql-server-2005
etl
spaghetticowboy
fonte
fonte
Respostas:
O tamanho máximo do lote para o SQL Server 2005 é 65.536 * NPS (Network Packet Size), em que o NPS geralmente é de 4KB. Isso funciona com 256 MB. Isso significaria que suas instruções de inserção teriam uma média de 5,8 KB cada. Isso não parece certo, mas talvez haja espaços estranhos ou algo incomum lá.
Minha primeira sugestão seria colocar uma instrução "GO" após cada instrução INSERT. Isso dividirá seu lote único de 45.000 instruções INSERT em 45.000 lotes separados. Isso deve ser mais fácil de digerir. Cuidado, se uma dessas inserções falhar, você pode ter dificuldade em encontrar o culpado. Você pode querer se proteger com uma transação. Você pode adicionar essas instruções rapidamente se o seu editor tiver uma boa pesquisa e substituição (que permitirá pesquisar e substituir caracteres de retorno como \ r \ n) ou um recurso de macro.
A segunda sugestão é usar um Assistente para importar os dados diretamente do Excel. O assistente cria um pequeno pacote SSIS para você, nos bastidores, e depois o executa. Não terá esse problema.
fonte
GO
after every statement? Well, I guess if you're generating them using another script that's OK. Otherwise, I'd just put one after every 1000INSERT
s. With regards to making the transaction atomic and minimizing the size of the transaction, why not load all the rows into a temp table or table variable and then load them in one shot from there to the target table?BULK INSERT
oubcp
parecer opções mais apropriadas do que 45.000 instruções de inserção.Se você precisar seguir as instruções de inserção, considerarei algumas opções:
R: Use transações e agrupe lotes de 100 ou 500 ou 1000 instruções em cada uma delas para minimizar o impacto no log e no lote. por exemplo
B: Em vez de instruções de inserção individuais, use
UNION ALL
para 100 ou 500 instruções de cada vez, por exemploEu deixei o tratamento de erros por questões de brevidade, mas o ponto é que nunca tentaria enviar um único lote de 45.000 instruções individuais para o SQL Server.
fonte
VARCHAR(800)
colunas em 2008 com um tempo de compilação de 12,5 minutos na minha instância de desenvolvimento de 2008, pois faz muito trabalho desnecessário na comparação de valores em vez de apenas inseri-los (executa muito mais rápido quando parametrizado e sem valores a serem observados). Embora tenha melhorado muito em 2012, o padrão não linear ainda existe e deve ser corrigido na versão posterior.Não sei por que você está recebendo o erro de falta de memória, mas existe uma abordagem mais fácil.
Se você pode exportar os dados da planilha para um formato delimitado (por exemplo, csv), pode usar o assistente de importação de dados no SSMS para inserir os dados para você:
fonte
Usando vários SqlBulkCopy, crie uma tabela temporária. Insira novos dados na tabela temporária e mescle os dados na tabela temporária na existente. Exemplo usando o método C # SqlBulkCopy.WriteToServer (DataTable) . Espero que ajude
fonte
Sim, nós poderíamos fazer isso, tentei com uma abordagem BCP (Bulk Copy Program) para evitar um problema de OutOfMemory .
Nota : Tentei no SQL Server 2014.
No BCP, primeiro precisamos exportar os dados do banco de dados de origem para o arquivo bcp (na pasta do diretório local) e depois importar esse arquivo bcp para o banco de dados de destino.
Abaixo estão os passos do bolo:
Nota:
a) Verifique se a tabela vazia está presente no banco de dados de destino
b) Verifique se a pasta Temp está presente na unidade C
Crie um arquivo bat chamado Export_Data.bat com o comando mostrado abaixo:
pausa
Execute esse arquivo bat, como resultado, um arquivo bcp será gerado na pasta Temp
Em seguida, crie um outro arquivo bat chamado Import_Data.bat com o seguinte comando:
Pausa
E aqui vamos nós!
fonte