¿Por qué este DataAdapter no inserta filas en la base de datos?
Entonces, tengo una situación en la que estoy usando un SqlDataAdapter para insertar filas en una tabla en una base de datos SQL Server 2014.
La fuente de los datos es una hoja de cálculo de Excel.
La inserción funciona bien cuando el objeto DataTable se rellena utilizando algunos bucles For y .Columns.Add y .Rows.Add para copiar los datos de la hoja de Excel. Este código de trabajo no lo he incluido aquí.
Sin embargo, estoy refactorizando el código para usar un OleDbDataReader. Aquí está mi función:
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
Cuando depuro, la DataTable que se devuelve de la función tiene datos en el conjunto, y de lo contrario parece ser idéntica a la DataTable de la versión anterior del código. Aquí está el código para actualizar la base de datos. Este código essin alterar para ambos casos
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
No se lanzan excepciones. La depuración de la línea adp.Update (dt) no tiene latencia como si la consulta no se ejecutara en absoluto. Esa es la única diferencia que noto entre el DT de filas / columnas agregadas y el DT poblado de OleDB: hay un ligero tiempo de latencia ya que los datos se insertan correctamente.
¿Me estoy perdiendo algún tipo de funcionalidad básica o propiedad de laDataTable
o tal vez una propiedad heredada o creada durante la carga? ¿Es algo más en lo que no he pensado? ¿Por qué miSqlDataAdapter
insertar datos en la base de datos cuando la fuente es unDataTable
creado manualmente versus unDataTable
llenado por elOleDbReader
?