【发布时间】:2016-06-08 11:56:33
【问题描述】:
我有一个 Windows 窗体应用程序,用户在其中选择一个 .csv 文件并单击导入。此时,该文件应使用 SqlBulkCopy 导入 SQL Server。 问题是我遇到了一些错误,我认为这是由于导入时字段为空。我收到此错误:
Input string was not in a correct format.Couldn't store <> in ScranDrugQuantity Column. Expected type is Int32.
这是 CSV 的示例
974524,416194,131179,For information only. ,17/05/2016 16:43:27,17/05/2016 16:43:27,1,xxxx xxxxx,xxxx xxxxx,1,Information about,930720,,320139002,1,3317411000001100,,1252,,5143,17/05/2016 16:42:51,17/05/2016 00:00:00,17/05/2016 16:43:27,0051431705161623286,3348074428,HS21X,,,
974522,416192,153168,information ,17/05/2016 16:42:54,17/05/2016 16:42:54,500,xxxxx xxxxxx,xxxxxxxx ,80,more information,930718,,,,,,,737,,4256,17/05/2016 16:42:13,17/05/2016 00:00:00,17/05/2016 16:42:54,31944C7C3AC04C4D92204775BBCEA365,3418645550,XX21,,,
974521,416192,153168,xxxxxxxxxxxxx ,17/05/2016 16:42:49,17/05/2016 16:42:49,500,xxxxxxxx xxxxxxxxx,xxxxxxxx,80,xxxxxxxx,930717,,,,,,,737,,4256,17/05/2016 16:42:13,17/05/2016 00:00:00,17/05/2016 16:42:49,31944C7C3AC04C4D92204775BBCEA365,3418645550,HS21,,,
这是我用来尝试导入的代码:
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim oTimer As New System.Diagnostics.Stopwatch
oTimer.Start()
Dim iRows As Int64 = 0
' & My.Settings.dbServer & ";uid=" & My.Settings.dbUsername & ";pwd=" & My.Settings.dbPassword & ";database=" & My.Settings.dbDatabase
Using oBulk As New Data.SqlClient.SqlBulkCopy("server=" & My.Settings.dbServer & ".;database=" & My.Settings.dbDatabase & ";trusted_connection=yes;uid=" & My.Settings.dbUsername & ";pwd=" & My.Settings.dbPassword, SqlClient.SqlBulkCopyOptions.TableLock) With
{.DestinationTableName = "Scripts", .BulkCopyTimeout = 0, .BatchSize = 100}
Using oSR As New IO.StreamReader(strFilename.Text)
Using oDT As New DataTable
With oDT.Columns
.Add("scriptID", Type.GetType("System.Int32"))
.Add("PrescriptionID", Type.GetType("System.Int32"))
.Add("StockID", Type.GetType("System.Int32"))
.Add("CautionsExpanded", Type.GetType("System.String"))
.Add("ScriptDateDispensed", Type.GetType("System.DateTime"))
.Add("ScriptDateLastChanged", Type.GetType("System.DateTime"))
.Add("PackSize", Type.GetType("System.Int32"))
.Add("PatientName", Type.GetType("System.String"))
.Add("PrescriberName", Type.GetType("System.String"))
.Add("Quantity", Type.GetType("System.Int32"))
.Add("ScriptDispensedAs", Type.GetType("System.String"))
.Add("ScriptNumber", Type.GetType("System.Int32"))
.Add("ScriptWrittenAs", Type.GetType("System.String"))
.Add("ScranDrugDmadCode", Type.GetType("System.String"))
.Add("ScranDrugQuantity", Type.GetType("System.Int32"))
.Add("ScanSnomedQuantity", Type.GetType("System.String"))
.Add("ScanSnomedUnit", Type.GetType("System.String"))
.Add("ScanDrugDosage", Type.GetType("System.String"))
.Add("GMSNo", Type.GetType("System.Int32"))
.Add("GMSPrice", Type.GetType("System.String"))
.Add("PrescriberNumber", Type.GetType("System.String"))
.Add("PrescriptionDispensed", Type.GetType("System.DateTime"))
.Add("PrescriptionDatePrescribed", Type.GetType("System.DateTime"))
.Add("PrescriptionDateLastChanged", Type.GetType("System.DateTime"))
.Add("EPESPrescriptionID", Type.GetType("System.String"))
.Add("PersonCodePPSN", Type.GetType("System.String"))
.Add("FormName", Type.GetType("System.String"))
.Add("ExportedOn", Type.GetType("System.String"))
.Add("Completed", Type.GetType("System.String"))
.Add("Spare", Type.GetType("System.String"))
End With
Dim iBatchsize As Integer = 0
Do While Not oSR.EndOfStream
Dim sLine As String() = oSR.ReadLine.Split(CChar(","))
oDT.Rows.Add(sLine)
iBatchsize += 1
If iBatchsize = 100 Then
oBulk.WriteToServer(oDT)
oDT.Rows.Clear()
iBatchsize = 0
Console.WriteLine("Flushing 100,000 rows")
End If
iRows += 1
Loop
oBulk.WriteToServer(oDT)
oDT.Rows.Clear()
End Using
End Using
End Using
oTimer.Stop()
Console.WriteLine(iRows.ToString & "Records imported in " & oTimer.Elapsed.TotalSeconds & " seconds.")
Console.ReadLine()
End Sub
有没有办法插入一个默认值作为正在读入的 CSV,或者有没有办法阻止这个错误?
谢谢
【问题讨论】:
-
您的问题是您依赖 DataTable 将字段字符串表示形式隐式转换为各自的 .Net 类型。由于您的 CSV 包含空字段,因此您需要处理
String.Split函数返回的字符串数组,并为空值分配一个可解析的字符串值。
标签: sql vb.net csv sqlbulkcopy