2016-06-08 1 views
0

사용자가 .csv 파일을 선택하고 가져 오기를 클릭하는 Windows 양식 응용 프로그램이 있습니다. 이 시점에서 파일은 SqlBulkCopy를 사용하여 SQL Server로 가져와야합니다. 문제점 일부 오류가 발생하고 가져 오기에서 필드가 비어있는 것으로 생각됩니다. 를 삽입 할 수있는 방법이 있나요CSV에서 데이터베이스로 가져오고 SqlBulkCopy를 사용하여 문제가 발생했습니다.

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

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,,, 

을 Heres 코드의 샘플입니다

Input string was not in a correct format.Couldn't store <> in ScranDrugQuantity Column. Expected type is Int32. 

: 임은이 오류가 읽혀지는 CSV로 기본 값 또는이 오류를 막을 수있는 방법이 있습니까?

감사

+0

문제는 사용자가 DataTable을 사용하여 필드 문자열 표현을 각각의 .Net 유형으로 암시 적으로 변환하는 것입니다. CSV에 빈 필드가 포함되어 있으므로 String.Split 함수에서 반환 한 String 배열을 처리하고 빈 값에 구문 분석 가능한 문자열 값을 할당해야합니다. – TnTinMn

답변

1

당신은 널 (null)에 sLine 배열에 빈 문자열을 변환해야합니다는, 그렇지 않으면 DataTable 시도하고 컬럼에 대해 정의 된 데이터 형식으로 값을 변환하는 것입니다. 예 : LINQ 사용 :

Dim sLine As String() = oSR.ReadLine() _ 
    .Split(CChar(",")) _ 
    .Select(Function(x) If(String.IsNullOrEmpty(x), Nothing, x)) _ 
    .ToArray() 
관련 문제