2017-09-21 13 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 

、関数から返されたDataTableは、セット内のデータを持っており、それ以外の場合は、コードの以前のバージョンからのDataTableと同じように見えます。データベースを更新するコードは次のとおりです。どちらの場合も、このコードはに変更されずにです。

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は、DataTableDataTableで手作業で作成された場合に、データがOleDbReaderで埋められた場合、そのデータをデータベースに挿入するのはなぜですか?

+1

myDA.AcceptChangesDuringFill = False ... rows = myDA.Fill(xlDT) 
'DataTable'各行の' RowState'を追跡し、それらがすべてである 'Added'ため手動加算ループは動作します。これは、別のデータストアからデータを移行するために非常に有用です。他のソースから読み込んだ場合、それらは追加/新規作成されません。 (まだそのコードを渡して) – Plutonix

+0

adp.updateではなくcmd.ExecuteNonQueryを使ってみましたか? – Benno

+0

dataadapterを使用してテーブルを塗りつぶした場合は、 'myDA.AcceptChangesDuringFill = False'を使用して行状態フラグをクリアすることはできません – Plutonix

答えて

2

手動ループでデータを追加し、その行のRowStateを追跡DataTableそれぞれは、彼らがすべてのAddedであるため、( - そのそれは手動でDataTableを作成するとは関係ありません)動作します。 Excelのような他のソースからロードすると、ではなく、が追加/新規になります。あなたは、テーブルを埋めるためにDataAdapterを使用する場合は

、あなたはそれをそのままにRowStateを設定していない伝えることができます。

関連する問題