Question:
J'ai un script avec environ 45 000 insertions de déclarations sélectionnées. Lorsque j'essaye de l'exécuter, j'obtiens un message d'erreur indiquant que je n'ai plus de mémoire. Comment puis-je exécuter ce script?
Le contexte:
- Ajout de nouveaux champs de données pour rendre une application agréable avec une autre application utilisée par le client.
- Vous avez obtenu une feuille de calcul du client pleine de données qui a mappé les éléments de données actuels aux valeurs de ces nouveaux champs.
- Feuille de calcul convertie pour insérer des instructions.
- Si je n'exécute que certaines des instructions, cela fonctionne, mais pas tout le script.
- Non, il n'y a pas de fautes de frappe.
S'il y a une manière différente de charger ces données, n'hésitez pas à me châtier et à me le faire savoir.
sql-server
sql-server-2005
etl
spaghetticowboy
la source
la source
Réponses:
La taille de lot maximale pour SQL Server 2005 est de 65 536 * taille de paquet réseau (NPS), où NPS est généralement de 4 Ko. Cela équivaut à 256 Mo. Cela signifierait que vos instructions d'insertion seraient en moyenne de 5,8 Ko chacune. Cela ne semble pas juste, mais il y a peut-être des espaces étrangers ou quelque chose d'inhabituel là-dedans.
Ma première suggestion serait de mettre une instruction "GO" après chaque instruction INSERT. Cela divisera votre lot unique de 45 000 instructions INSERT en 45 000 lots distincts. Cela devrait être plus facile à digérer. Soyez prudent, si l'un de ces inserts échoue, vous aurez peut-être du mal à trouver le coupable. Vous voudrez peut-être vous protéger avec une transaction. Vous pouvez ajouter ces instructions rapidement si votre éditeur a une bonne fonction de recherche et remplacement (qui vous permettra de rechercher et de remplacer les caractères de retour comme \ r \ n) ou une fonction de macro.
La deuxième suggestion consiste à utiliser un assistant pour importer les données directement à partir d'Excel. L'Assistant crée un petit package SSIS pour vous, dans les coulisses, puis l'exécute. Il n'aura pas ce problème.
la source
GO
après chaque déclaration? Eh bien, je suppose que si vous les générez en utilisant un autre script, c'est OK. Sinon, je n'en mettrais qu'un après toutes les 1000INSERT
s. Pour ce qui est de rendre la transaction atomique et de minimiser la taille de la transaction, pourquoi ne pas charger toutes les lignes dans une table temporaire ou une variable de table, puis les charger en une seule fois de là vers la table cible?BULK INSERT
oubcp
semblent des options plus appropriées que 45 000 instructions d'insertion.Si vous devez vous en tenir aux instructions d'insertion, je considérerais quelques options:
R: Utilisez des transactions et encapsulez des lots de 100, 500 ou 1 000 relevés dans chacun pour minimiser l'impact sur le journal et le lot. par exemple
B: Au lieu d'instructions d'insertion individuelles, utilisez
UNION ALL
pour 100 ou 500 instructions à la fois, par exempleJ'ai laissé la gestion des erreurs par souci de concision, mais le fait est que je n'essaierais jamais d'envoyer un seul lot de 45 000 instructions individuelles à SQL Server.
la source
VARCHAR(800)
colonnes sur 2008 avec un temps de compilation de 12,5 minutes sur mon instance de développement 2008 car il fait beaucoup de travail inutile en comparant les valeurs plutôt que de simplement les insérer (effectue beaucoup plus rapide une fois paramétré et aucune valeur à regarder). Bien que beaucoup amélioré en 2012, le modèle non linéaire existe toujours et devrait être corrigé dans la version après.Je ne sais pas pourquoi vous obtenez l'erreur de mémoire insuffisante, mais il existe une approche plus simple.
Si vous pouvez exporter les données de la feuille de calcul dans un format délimité (par exemple csv), vous pouvez utiliser l'assistant d'importation de données dans SSMS pour insérer les données pour vous:
la source
À l'aide de plusieurs SqlBulkCopy, créez une table temporaire. Insérez de nouvelles données dans la table temporaire, puis fusionnez les données de la table temporaire dans la table existante. Exemple utilisant la méthode C # SqlBulkCopy.WriteToServer (DataTable) . J'espère que ça aide
la source
Oui, nous avons pu le faire, j'ai essayé avec une approche BCP (Bulk Copy Program) afin d'éviter un problème OutOfMemory .
Remarque : essayé sur SQL Server 2014.
Dans BCP, nous devons d'abord exporter les données de la base de données source vers le fichier bcp (dans le dossier du répertoire local), puis nous devons importer ce fichier bcp dans la base de données de destination.
Voici les étapes de la marche du gâteau:
Remarque:
a) Assurez-vous que la table vide est présente dans la base de données de destination
b) Assurez-vous que le dossier Temp est présent dans le lecteur C
Créez un fichier bat nommé Export_Data.bat avec la commande ci-dessous:
pause
Exécutez ce fichier bat, à la suite d'un fichier bcp sera généré dans le dossier Temp
Créez ensuite un autre fichier bat nommé Import_Data.bat avec la commande suivante:
Pause
Et c'est reparti!
la source