2017-09-21 94 views
2

所以我有一種情況,我正在使用SqlDataAdapter將行插入到SQL Server 2014數據庫中的表中。爲什麼DataAdapter不能將行插入數據庫?

數據的來源是Excel電子表格。

當DataTable對象使用幾個For循環和.Columns.Add和.Rows.Add來複制Excel表格中的數據時,插入工作正常。這個工作代碼我沒有包括在這裏。

但是,我重構代碼以使用OleDbDataReader。這裏是我的功能:

Private Function FillDataTable(path As String, name As String) As DataTable 
     Dim fullpath As String = path 
     Dim wsname As String = name 
     Dim dt = New DataTable() 
     Try 
      Dim connectionstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & fullpath & "';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'" 
      Dim commandstring As String = "Select * From " & wsname 
      Using con As New OleDbConnection(connectionstring) 
       Using cmd As New OleDbCommand(commandstring, con) 
        con.Open() 
        Using dr As OleDbDataReader = cmd.ExecuteReader() 
         With dt 
          For Each c In aryFieldList 
           .Columns.Add(c.FieldName, ConvertType(c.DataType)) 
          Next 

          .Columns.Add("SubmID") 
          .Columns("SubmID").DefaultValue = 0 

          .Columns.Add("S_ORDER") 
          .Columns("S_ORDER").DefaultValue = 0 

          .Columns.Add("C_ORDER") 
          .Columns("C_ORDER").DefaultValue = 0 
         End With 
         dt.Load(dr) 
        End Using 
       End Using 
      End Using 

     Catch ex As Exception 
      MsgBox(ex.Message) 
     End Try 
     Return dt 

    End Function 

當我調試,數據表是從函數返回有數據的集合,否則似乎等同於以前版本的代碼的數據表。以下是更新數據庫的代碼。對於這兩種情況,該代碼是不變的

Dim dt = New DataTable() 
    dt = FillDataTable(fullpath, wsname) 

Using cn = New SqlConnection(ConfigurationManager.ConnectionStrings("Connection").ConnectionString) 
    cn.Open() 
    Using adp = New SqlDataAdapter() 
     Dim sb As New StringBuilder 

     [...StringBuilder code to build the Insert command here...] 

     Dim cmd As New SqlCommand(sb.ToString, cn) 

     With adp 
      .InsertCommand = cmd 
      .InsertCommand.Parameters.Add("SubmID", SqlDbType.Int, 1, "SubmID") 
      .InsertCommand.Parameters.Add("S_ORDER", SqlDbType.Int, 1, "S_ORDER") 
      .InsertCommand.Parameters.Add("C_ORDER", SqlDbType.Int, 1, "C_ORDER") 

      For Each p In aryFieldList 
       If p.Excluded = False Then 
        .InsertCommand.Parameters.Add(p.FieldName, p.DataType, p.Length, p.FieldName) 
       End If 
      Next 
       adp.Update(dt) 

     End With 'adp 
    End Using 'adp 
End Using 'cn 

沒有發生任何異常。調試adp.Update(dt)行沒有延遲,就好像查詢根本沒有執行一樣。這是我注意到在添加DT和OleDB填充DT的行/列之間唯一的區別 - 數據成功插入後,存在一個小的延遲時間。

我是否缺少DataTable的某種基本功能或屬性,或者可能是在加載期間繼承或創建的屬性?這是我還沒有想到的其他東西嗎?爲什麼我的SqlDataAdapter將數據插入數據庫時​​,手動創建的是DataTable,而DataTableOleDbReader填充?

+1

一個'DataTable'跟蹤每一行的'RowState',所以手動添加循環工作,因爲他們都是'Added'。如果您從其他來源加載,則不會添加/新增。 (仍涉及通過該代碼) – Plutonix

+0

您是否嘗試過使用cmd.ExecuteNonQuery而不是adp.update? – Benno

+0

如果使用dataadapter填充表格,則可以使用'myDA.AcceptChangesDuringFill = False',這樣行狀態標誌不會被清除 – Plutonix

回答

2

每個DataTable跟蹤其行RowState,所以手動在一個循環中添加數據的工作,因爲他們都是Added(它無關,與手動創建DataTable - 其)。當您從Excel等其他來源加載時,它們是而不是已添加/新建。

如果您使用DataAdapter來填充表格,則可以告知它而不是以將RowState設置爲不變。這是從一個數據存儲遷移到另一個數據非常有用:

myDA.AcceptChangesDuringFill = False 
... 
rows = myDA.Fill(xlDT) 
相關問題