如何用另一个数据表中的数据更新空数据表
how to update empty datatable by the data from another datatable
我有 2 个服务器,它们包含具有相同结构的相同数据库(主服务器 + 子服务器)。
- 我删除了子服务器中 table 的所有数据。
- 我从主服务器获取了table的数据并将其放入Datatable.
- 我从server2的Datatable复制了数据
- 我使用Dataadapter2更新子服务器中的table。
可是,副服还是空的?!
'Delete Data From The Sub Server
xSlConn.Open()
Dim xcmddelete As New MySqlCommand("Delete FROM tblplaces", xSlConn)
xcmddelete.ExecuteNonQuery()
'Get Data Drom The Main Server
Conn.Open()
Dim xcmd1 As New MySqlCommand("SELECT * FROM tblplaces", Conn)
Dim xdt1 As New DataTable
Dim xda1 As New MySqlDataAdapter(xcmd1)
xda1.Fill(xdt1)
'Preparing the datatable for the Sub Server
Dim xcmd As New MySqlCommand("SELECT * FROM tblplaces", xSlConn)
Dim xdt2 As New DataTable
Dim xda2 As New MySqlCommand(xcmd)
Dim xB As New MySqlCommandBuilder(xda2)
xda2.Fill(xdt2)
'Copt the data from the main datatable to the sub datatable
xdt2 = xdt1.Copy()
'Update The Datatable2
xB.GetUpdateCommand()
xda2.Update(xdt2)
xda2.Fill(xdt2)
这行代码没用;无论如何,下一行代码都会抛出 xdt2
xdt2 = xdt1.Copy()
这一行重复了数据table。它 不会 将 xdt2
中的所有行设置为 Added
的 RowState
,这是数据适配器需要的,以便运行 插页
数据适配器检查每一行的 RowState。 Unchanged
行被忽略。 Added
在它们上面有 INSERT 命令 运行,Modified
映射到 UPDATE,Deleted
映射到 DELETE 查询
现在你的 xdt1 中的所有行都是 Unchanged
因为数据适配器在将它们添加到 table
之后调用了它们 AcceptChanges
现在..您根本不需要复制数据;您可以将 xdt1 中的所有行设置为添加,这样 xdt2 适配器将对它们使用其 INSERT 命令。此外,应该可以在 insertcommand
上交换连接
'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.Fill(dt)
Dim xB As New MySqlCommandBuilder(da)
da.InsertCommand.Connection = xSlConn
For Each ro as DataRow in xdt1.Rows
ro.SetAdded()
Next ro
da.Update(dt)
或者,您可以简单地请求 xda1
适配器根本不对它们调用 AcceptChanges,这样它们就已经处于已添加状态:
'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.AcceptChangesDuringFill = False
da.Fill(dt)
Dim xB As New MySqlCommandBuilder(da)
da.InsertCommand.Connection = xSlConn
da.Update(dt)
或者如果您要推送到不同的数据库
'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.AcceptChangesDuringFill = False
da.Fill(dt)
Dim da2 as New SqliteDataAdapter("SELECT * FROM tblplaces", "put a connection string here")
Dim xB As New SqliteCommandBuilder(da2)
da2.Update(dt)
注意;后一个示例使用 SQLite 作为演示,为不同的数据库声明两个不同类型的不同适配器 - 它不能保证例如您正在使用的特定 SQLite 库实际上包含数据适配器实现(有些不)
首先,您需要使用 Using...End Using
块来确保您的数据库对象已被释放。不要在使用它们的方法之外声明数据库连接和命令。
您的主要问题是 DataAdapter
的 Fill
方法将所有行设置为未更改。我将其更改为采用 LoadOption
参数的 DataTable.Load
方法。这将保留 RowState
Added
。然后,当您在 DataAdapter
上调用 Update
时,该行将被识别。如果该行是 Unchanged
,则 DataAdapter
将不会更新数据库。
Private ConStrMain As String = "Your Main server connection string"
Private ConStrSub As String = "Your Sub server connection string"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Delete Data From The Sub Server
Using conSub As New MySqlConnection(ConStrSub),
cmd As New MySqlCommand("Delete FROM tblplaces", conSub)
conSub.Open()
cmd.ExecuteNonQuery()
End Using
'Retrieve data from Main server
Dim dt As New DataTable
Using conMain As New MySqlConnection(ConStrMain),
cmd As New MySqlCommand("SELECT * FROM tblplaces", conMain)
conMain.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader, LoadOption.Upsert)
End Using
End Using
'Insert data from Main to Sub server
Using conSub As New MySqlConnection(ConStrSub),
da As New MySqlDataAdapter("SELECT * FROM tblplaces", conSub)
Dim sb As New MySqlCommandBuilder(da)
da.Update(dt)
End Using
End Sub
我有 2 个服务器,它们包含具有相同结构的相同数据库(主服务器 + 子服务器)。
- 我删除了子服务器中 table 的所有数据。
- 我从主服务器获取了table的数据并将其放入Datatable.
- 我从server2的Datatable复制了数据
- 我使用Dataadapter2更新子服务器中的table。
可是,副服还是空的?!
'Delete Data From The Sub Server
xSlConn.Open()
Dim xcmddelete As New MySqlCommand("Delete FROM tblplaces", xSlConn)
xcmddelete.ExecuteNonQuery()
'Get Data Drom The Main Server
Conn.Open()
Dim xcmd1 As New MySqlCommand("SELECT * FROM tblplaces", Conn)
Dim xdt1 As New DataTable
Dim xda1 As New MySqlDataAdapter(xcmd1)
xda1.Fill(xdt1)
'Preparing the datatable for the Sub Server
Dim xcmd As New MySqlCommand("SELECT * FROM tblplaces", xSlConn)
Dim xdt2 As New DataTable
Dim xda2 As New MySqlCommand(xcmd)
Dim xB As New MySqlCommandBuilder(xda2)
xda2.Fill(xdt2)
'Copt the data from the main datatable to the sub datatable
xdt2 = xdt1.Copy()
'Update The Datatable2
xB.GetUpdateCommand()
xda2.Update(xdt2)
xda2.Fill(xdt2)
这行代码没用;无论如何,下一行代码都会抛出 xdt2
xdt2 = xdt1.Copy()
这一行重复了数据table。它 不会 将 xdt2
中的所有行设置为 Added
的 RowState
,这是数据适配器需要的,以便运行 插页
数据适配器检查每一行的 RowState。 Unchanged
行被忽略。 Added
在它们上面有 INSERT 命令 运行,Modified
映射到 UPDATE,Deleted
映射到 DELETE 查询
现在你的 xdt1 中的所有行都是 Unchanged
因为数据适配器在将它们添加到 table
AcceptChanges
现在..您根本不需要复制数据;您可以将 xdt1 中的所有行设置为添加,这样 xdt2 适配器将对它们使用其 INSERT 命令。此外,应该可以在 insertcommand
上交换连接'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.Fill(dt)
Dim xB As New MySqlCommandBuilder(da)
da.InsertCommand.Connection = xSlConn
For Each ro as DataRow in xdt1.Rows
ro.SetAdded()
Next ro
da.Update(dt)
或者,您可以简单地请求 xda1
适配器根本不对它们调用 AcceptChanges,这样它们就已经处于已添加状态:
'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.AcceptChangesDuringFill = False
da.Fill(dt)
Dim xB As New MySqlCommandBuilder(da)
da.InsertCommand.Connection = xSlConn
da.Update(dt)
或者如果您要推送到不同的数据库
'Get Data Drom The Main Server
Dim dt As New DataTable
Dim da As New MySqlDataAdapter("SELECT * FROM tblplaces", Conn)
da.AcceptChangesDuringFill = False
da.Fill(dt)
Dim da2 as New SqliteDataAdapter("SELECT * FROM tblplaces", "put a connection string here")
Dim xB As New SqliteCommandBuilder(da2)
da2.Update(dt)
注意;后一个示例使用 SQLite 作为演示,为不同的数据库声明两个不同类型的不同适配器 - 它不能保证例如您正在使用的特定 SQLite 库实际上包含数据适配器实现(有些不)
首先,您需要使用 Using...End Using
块来确保您的数据库对象已被释放。不要在使用它们的方法之外声明数据库连接和命令。
您的主要问题是 DataAdapter
的 Fill
方法将所有行设置为未更改。我将其更改为采用 LoadOption
参数的 DataTable.Load
方法。这将保留 RowState
Added
。然后,当您在 DataAdapter
上调用 Update
时,该行将被识别。如果该行是 Unchanged
,则 DataAdapter
将不会更新数据库。
Private ConStrMain As String = "Your Main server connection string"
Private ConStrSub As String = "Your Sub server connection string"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Delete Data From The Sub Server
Using conSub As New MySqlConnection(ConStrSub),
cmd As New MySqlCommand("Delete FROM tblplaces", conSub)
conSub.Open()
cmd.ExecuteNonQuery()
End Using
'Retrieve data from Main server
Dim dt As New DataTable
Using conMain As New MySqlConnection(ConStrMain),
cmd As New MySqlCommand("SELECT * FROM tblplaces", conMain)
conMain.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader, LoadOption.Upsert)
End Using
End Using
'Insert data from Main to Sub server
Using conSub As New MySqlConnection(ConStrSub),
da As New MySqlDataAdapter("SELECT * FROM tblplaces", conSub)
Dim sb As New MySqlCommandBuilder(da)
da.Update(dt)
End Using
End Sub