我遇到的问题是SqlBulkCopy
没有将列中的所有数据复制到目标表。我已经验证了源数据(这是一个.CSV
文件)在所有行的列中都有值,但只复制了该列中的前40行左右。
目标表格的列设置为NVARCHAR(255)
,所有这些列都可以为空。
这是我执行批量复制的功能:
Private Sub loadDataFromCSV(ByVal pathToFile As String, ByVal connString As String, ByVal file As String, ByVal colCount As Integer)
Dim fileLocation As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathToFile & ";Extended Properties='text;HDR=NO;FMT=Delimited(,)';"
Dim qry As String = "select * from " & file
Dim CompData As OleDbDataReader
Using destConnection As SqlConnection = _
New SqlConnection(connString)
destConnection.Open()
Using sourceConnection As New OleDbConnection(fileLocation)
Dim cmdSourceData As New OleDbCommand(qry, sourceConnection)
sourceConnection.Open()
CompData = cmdSourceData.ExecuteReader()
Using bulkCopy As SqlClient.SqlBulkCopy = New SqlClient.SqlBulkCopy(connString)
bulkCopy.DestinationTableName = "dbo.Records"
bulkCopy.BatchSize = 10000
bulkCopy.BulkCopyTimeout = 90
Try
bulkCopy.WriteToServer(CompData)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
CompData.Close()
End Try
End Using
End Using
End Using
End Sub
据我所知,表中的所有数据都会将其转换为正确的列,但第7列除外。在第7列中,我得到前40行左右的数据,然后列的其余值为NULL。
我已经对可能出错的问题用尽了,所以任何帮助都会受到高度赞赏。
感谢。
答案 0 :(得分:0)
我的猜测是它是转换错误。 OLEDB将根据前8行(我认为)推断列的数据类型,所以如果您的第一行是:
SomeColumn
----------
1
2
3
4
5
6
7
8
9
apple
这最初看起来像一个整数列,所以这是它映射到的,但是当它到达“apple”时它不能将它转换为整数,所以返回DbNull。
解决方案是将IMEX=1
添加到连接字符串中,这意味着不会进行隐式转换,而OleDbReader将只读取csv中的内容。
这样做的缺点是,在尝试调用SqlBulkCopy.WriteToServer(DataReader)
方法时,您可能会遇到转换错误。您可能需要以与数据库表相同的格式创建DataTable,并在必要时迭代OleDbReader进行显式转换,然后使用SqlBulkCopy将此DataTable写入数据库。
答案 1 :(得分:0)
作为一个变通的解决方法,我只是将一个字符串放入csv文件前8行的每一列中。它愚弄sqlbulkcopy将所有字段都视为字符串。然后在sql中删除包含字符串的记录。