为什么这个 DataAdapter 不向数据库中插入行?
Why won't this DataAdapter insert rows into the database?
所以我有一种情况,我正在使用 SqlDataAdapter 将行插入 SQL Server 2014 数据库中的 table。
数据来源是Excel价差sheet。
当使用几个 For 循环填充 DataTable 对象并使用 .Columns.Add 和 .Rows.Add 从 Excel sheet 复制数据时,插入工作正常.我没有在此处包含此工作代码。
但是,我正在重构代码以使用 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) 行没有延迟,就好像根本没有执行查询一样。这是我注意到 Rows/Columns 添加的 DT 和 OleDB 填充的 DT 之间的唯一区别 -- 成功插入数据时有轻微的延迟时间。
我是否缺少某种基本功能或 DataTable
的 属性 或者可能是在加载期间继承或创建的 属性?这是我没有想到的其他事情吗?当源是手动创建的 DataTable
而不是 OleDbReader
填充的 DataTable
时,为什么我的 SqlDataAdapter
将数据插入数据库?
每个 DataTable
跟踪其行的 RowState
,因此在循环中手动添加数据是可行的,因为它们都是 Added
(与手动创建 Added
无关) =11=] - 它是 行 )。当您从 Excel 等其他来源加载时,它们是 而不是 added/new。
如果您使用 DataAdapter
来填充 table,您可以告诉它 而不是 以将 RowState
设置为未更改。这对于将数据从一个数据存储迁移到另一个非常有用:
myDA.AcceptChangesDuringFill = False
...
rows = myDA.Fill(xlDT)
我遇到了同样的问题,解决方案非常简单,一旦你看到它...我的数据库在 Visual studio,它的 属性 "Copy to Output Directory"被设置为 "Copy always",而不是 "Do not copy"。所以每次我是 运行 我的代码时,数据库都被删除了!
解决方案:
- 修改您的连接字符串,使其直接指向您的数据库
- 将您的数据库 属性 更改为 "Do not copy"
所以我有一种情况,我正在使用 SqlDataAdapter 将行插入 SQL Server 2014 数据库中的 table。
数据来源是Excel价差sheet。
当使用几个 For 循环填充 DataTable 对象并使用 .Columns.Add 和 .Rows.Add 从 Excel sheet 复制数据时,插入工作正常.我没有在此处包含此工作代码。
但是,我正在重构代码以使用 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) 行没有延迟,就好像根本没有执行查询一样。这是我注意到 Rows/Columns 添加的 DT 和 OleDB 填充的 DT 之间的唯一区别 -- 成功插入数据时有轻微的延迟时间。
我是否缺少某种基本功能或 DataTable
的 属性 或者可能是在加载期间继承或创建的 属性?这是我没有想到的其他事情吗?当源是手动创建的 DataTable
而不是 OleDbReader
填充的 DataTable
时,为什么我的 SqlDataAdapter
将数据插入数据库?
每个 DataTable
跟踪其行的 RowState
,因此在循环中手动添加数据是可行的,因为它们都是 Added
(与手动创建 Added
无关) =11=] - 它是 行 )。当您从 Excel 等其他来源加载时,它们是 而不是 added/new。
如果您使用 DataAdapter
来填充 table,您可以告诉它 而不是 以将 RowState
设置为未更改。这对于将数据从一个数据存储迁移到另一个非常有用:
myDA.AcceptChangesDuringFill = False
...
rows = myDA.Fill(xlDT)
我遇到了同样的问题,解决方案非常简单,一旦你看到它...我的数据库在 Visual studio,它的 属性 "Copy to Output Directory"被设置为 "Copy always",而不是 "Do not copy"。所以每次我是 运行 我的代码时,数据库都被删除了!
解决方案: - 修改您的连接字符串,使其直接指向您的数据库 - 将您的数据库 属性 更改为 "Do not copy"