J'essaie de charger une grande quantité de données dans SQL Server à partir d'un fichier plat à l'aide d'un insert en vrac. Cependant, mon fichier comporte un nombre variable de colonnes, par exemple, la première ligne contient 14 et la seconde contient 4. C'est bon, je veux simplement créer une table avec le nombre maximum de colonnes et charger le fichier avec des nulls pour le colonnes manquantes. Je peux jouer avec ça à partir de ce point. Mais il semble que SQL Server, lors de la fin de la ligne et d'avoir plus de colonnes à remplir pour la même ligne de la table de destination, passe simplement sur la ligne suivante et tente de mettre les données sur cette ligne à la mauvaise colonne de La table.
Y a-t-il un moyen d'obtenir le comportement que je cherche? Y a-t-il une option que je peux utiliser pour spécifier cela? Quelqu'un a-t-il couru dans cela avant? P>
Voici le code P>
BULK INSERT #t FROM '<path to file>' WITH ( DATAFILETYPE = 'char', KEEPNULLS, FIELDTERMINATOR = '#' )
5 Réponses :
Essayez de spécifier un terminateur de ligne avec votre terminaison de champ.
BULK INSERT #t FROM '<path to file>' WITH ( DATAFILETYPE = 'char', KEEPNULLS, FIELDTERMINATOR = '#', ROWTERMINATOR = '\n' --Or whatever signifies the end of a row in your flatfile. )
Le nombre de colonnes variables signifie qu'il ne peut pas être analysé par le code d'insertion en vrac. Comment connaît-il le nombre correct de colonnes? Et si vous fournissez trop? P>
Vous devrez le télécharger sur une table avec 4 colonnes et diviser le reste plus tard (ou une grande colonne). Ou pré-traiter pour générer un nombre égal de colonnes. P>
L'insert en vrac n'est pas particulièrement flexible. Un travail de travail est de charger chaque ligne de données dans une table provisoire contenant une seule colonne de varcharine. Une fois chargé, vous analysez ensuite chaque ligne en utilisant vos propres routines. p>
Une autre solution consiste à préproduire le fichier. Il peut être plus facile d'écrire un petit programme autonome pour ajouter des terminateurs à chaque ligne afin qu'il puisse être chargé en vrac correctement que pour analyser les lignes à l'aide de T-SQL.
Voici un exemple dans VB6 / VBA. Ce n'est certainement pas aussi rapide que l'insert en vrac SQL Server, mais il vient de prétraiter 91 000 lignes en 10 secondes. P>
Sub ColumnDelimiterPad(FileName As String, OutputFileName As String, ColumnCount As Long, ColumnDelimiter As String, RowDelimiter As String) Dim FileNum As Long Dim FileData As String FileNum = FreeFile() Open FileName For Binary Access Read Shared As #FileNum FileData = Space$(LOF(FileNum)) Debug.Print "Reading File " & FileName & "..." Get #FileNum, , FileData Close #FileNum Dim Patt As VBScript_RegExp_55.RegExp Dim Matches As VBScript_RegExp_55.MatchCollection Set Patt = New VBScript_RegExp_55.RegExp Patt.IgnoreCase = True Patt.Global = True Patt.MultiLine = True Patt.Pattern = "[^" & RowDelimiter & "]+" Debug.Print "Parsing..." Set Matches = Patt.Execute(FileData) Dim FileLines() As String Dim Pos As Long Dim MissingDelimiters ReDim FileLines(Matches.Count - 1) For Pos = 0 To Matches.Count - 1 If (Pos + 1) Mod 10000 = 0 Then Debug.Print Pos + 1 FileLines(Pos) = Matches(Pos).Value MissingDelimiters = ColumnCount - 1 - Len(FileLines(Pos)) + Len(Replace(FileLines(Pos), ColumnDelimiter, "")) If MissingDelimiters > 0 Then FileLines(Pos) = FileLines(Pos) & String(MissingDelimiters, ColumnDelimiter) Next If (Pos + 1) Mod 10000 <> 0 Then Debug.Print Pos + 1 If Dir(OutputFileName) <> "" Then Kill OutputFileName Open OutputFileName For Binary Access Write Lock Read Write As #FileNum Debug.Print "Writing " & OutputFileName & "..." Put #FileNum, , Join(FileLines, RowDelimiter) Close #FileNum Debug.Print "Done." End Sub
Dans la colonne Dernière table, vous trouverez tous les éléments de repos (y compris votre séparateur d'élément) p> S'il est nécessaire pour vous, créez une autre table pleine colocolue, copiez toutes les colonnes de la première. Table, et faites des analyses que sur la dernière colonne. p> exemple de fichier p> ressemblera à ceci dans votre table: p>
c1 | c2 | c3
"alpha" | "beta" | "gamma"
"one" | "two" | "three , four"