如何用另一个数据表中的数据更新空数据表

how to update empty datatable by the data from another datatable

我有 2 个服务器,它们包含具有相同结构的相同数据库(主服务器 + 子服务器)。

  1. 我删除了子服务器中 table 的所有数据。
  2. 我从主服务器获取了table的数据并将其放入Datatable.
  3. 我从server2的Datatable复制了数据
  4. 我使用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 中的所有行设置为 AddedRowState,这是数据适配器需要的,以便运行 插页

数据适配器检查每一行的 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 块来确保您的数据库对象已被释放。不要在使用它们的方法之外声明数据库连接和命令。

您的主要问题是 DataAdapterFill 方法将所有行设置为未更改。我将其更改为采用 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