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"