我正在尝试使用BULK INSERT从平面文件加载SQL服务器中的大量数据。但是,我的文件具有不同数量的列,例如第一行包含14,第二行包含4.这没关系,我只想创建一个具有最大列数的表,并将文件加载到其中,其中包含NULL缺少列。从那时起我就可以玩它。但似乎SQL Server在到达行尾并且有更多列填充目标表中的同一行时,只是转到下一行并尝试将该行上的数据放到错误的列中桌子。
有没有办法获得我正在寻找的行为?有没有可以用来指定它的选项?有没有人遇到过这个?
这是代码
BULK INSERT #t
FROM '<path to file>'
WITH
(
DATAFILETYPE = 'char',
KEEPNULLS,
FIELDTERMINATOR = '#'
)
答案 0 :(得分:5)
BULK INSERT不是特别灵活。一种解决方法是将每行数据加载到包含单个大varchar列的临时表中。加载后,然后使用自己的例程解析每一行。
答案 1 :(得分:2)
另一种解决方法是预处理文件。编写一个小的独立程序来为每一行添加终结符可能更容易,因此可以正确加载BULK,而不是使用T-SQL解析行。
这是VB6 / VBA中的一个示例。它肯定没有SQL Server批量插入那么快,但它只是在10秒内预处理了91000行。
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
答案 2 :(得分:2)
我的解决方法(在T-SQL中测试):
在上一个表格列中,您会找到所有其他项目(包括您的项目分隔符)
如果您需要,请创建另一个完整列表,从第一个表复制所有列,并仅在最后一列上进行一些解析。
示例文件
alpha , beta , gamma
one , two , three , four
在您的表格中将如下所示:
c1 | c2 | c3
"alpha" | "beta" | "gamma"
"one" | "two" | "three , four"
答案 3 :(得分:1)
不同数量的列意味着批量插入代码无法解析它。 它如何知道正确的列数?如果供应太多会怎么样?
你必须将它上传到一个包含4列的表中,然后将其余部分(或一个大列)拆分出来 或者预先处理它以生成相同数量的列。
答案 4 :(得分:-1)
尝试指定ROW终止符以及字段终止符。
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.
)
有关这方面的更多信息,请访问: