0

I have a dataset with data from two SQL tables in.

How can I update both tables with the updated dataset? (since join does not work)

             da = new SqlDataAdapter("select * from xxxx join.....", conn);
             builderForTable1 = new SqlCommandBuilder(da);
             da.Update(dataSetEmp, "Table");
4

3 回答 3

2

如果您提供给数据适配器的查询返回多个结果集,则 SQLDataAdapter.Fill() 方法可以执行此操作。

var da = new SqlDataAdapter("select * from customers; select * from orders;", conn);
da.Fill(myDataset);

var customersDataTable = myDataset.Tables[0];
var ordersDataTable = myDataset.Tables[1];

然后,您可以根据需要添加自己的 DataRelations。

myDataset.Relations.Add(new DataRelation(
    "CustomerOrders",
    customersDataTable.Columns["CustomerID"],
    ordersDataTable.Columns["CustomerID"]
)
于 2013-04-25T15:41:25.157 回答
1
Public Shared Function GetRecords(ByRef CNobj As System.Data.SqlClient.SqlConnection,
                                   ByRef RSobj As System.Data.DataSet,
                                   ByVal SQLquery As String,
                                   ByVal TableName() As String,
                                   Optional ByVal PrimKeys() As String = Nothing,
                                   Optional ByRef adapter As SqlDataAdapter = Nothing) As Integer

    On Error Resume Next
    Dim DataOkay As Integer = 0                             '[Set to negative if data bad]

    Dim suppliersAdapter As SqlDataAdapter = New SqlDataAdapter()

    'Create connection object, won't create if already exists
    If ConnectToDB(CNobj, False) = False Then
        'error creating object, Session("ErrorMsg") set by called code
        Return -1
    End If

    ' Open the connection.
    If CNobj.State = ConnectionState.Closed Then
        CNobj.Open()
    End If


    ' Create a SqlCommand to retrieve Suppliers data.
    Dim suppliersCommand As SqlCommand = New SqlCommand(SQLquery, CNobj)

    suppliersCommand.CommandType = CommandType.Text

    ' Set the SqlDataAdapter's SelectCommand.
    suppliersAdapter.SelectCommand = suppliersCommand


    ' Fill the DataSet.
    RSobj = New DataSet()
    suppliersAdapter.Fill(RSobj)
    If (Err.Number <> 0) Then
        DataOkay = -1
        _contexts.Session("ErrorMsg") = "Error reading records: " +
            DelDoubleQuotesInString(Err.Description)
        Call Err.Clear()
    ElseIf (RSobj.Tables.Count = 0) Then
        DataOkay = -2
        _contexts.Session("ErrorMsg") = "No tables read reading records for sql=" + SQLquery
    Else
        ' A table mapping names the DataTables.
        Dim IDX As Integer
        For IDX = 0 To TableName.Count - 1
            RSobj.Tables(IDX).TableName = TableName(IDX)
            If PrimKeys IsNot Nothing Then
                Dim primstr = PrimKeys(IDX)
                Dim primarr = Split(primstr, ",")
                Dim primcol(primarr.Count) As DataColumn
                Dim pidx As Integer
                For pidx = 0 To primarr.Count
                    primcol(pidx) = RSobj.Tables(IDX).Columns.Item(primarr(pidx))
                Next
                RSobj.Tables(IDX).PrimaryKey = primcol
            End If

        Next
        adapter = suppliersAdapter
    End If
    Return DataOkay
End Function

  Public Shared Function UpdateDB(ByRef dset As System.Data.DataSet, ByVal adapter As SqlDataAdapter)
    If dset.HasChanges = False Then
        Return True
    End If
    ' has multiple tables, select's separated by ;
    Dim SelectQry As String = adapter.SelectCommand.CommandText
    Dim commands() As String = Split(SelectQry, ";")
    Dim idx As Integer = 0

    For Each Table As System.Data.DataTable In dset.Tables
        'Connection object is global in shared ASP.NET module
        If CNobj.State = ConnectionState.Closed Then
            CNobj.Open()
        End If
        'Change select for table being updated.
        adapter.SelectCommand.CommandText = commands(idx)


        Dim cb As SqlCommandBuilder
        cb = New SqlCommandBuilder(adapter)

        adapter.InsertCommand = cb.GetInsertCommand(True)
        adapter.UpdateCommand = cb.GetUpdateCommand(True)
        adapter.DeleteCommand = cb.GetDeleteCommand(True)

        Try

            adapter.AcceptChangesDuringUpdate = True
            'force order delete, update, insert
            adapter.Update(Table.Select(Nothing, Nothing, DataViewRowState.Deleted))
            Table.AcceptChanges() 'Have to do after delete!
            adapter.Update(Table.Select(Nothing, Nothing, DataViewRowState.ModifiedCurrent))
            adapter.Update(Table.Select(Nothing, Nothing, DataViewRowState.Added))
        Catch
            HttpContext.Current.Session("ErrorMsg") = "Error saving data to DB: " + Err.Description
            adapter.SelectCommand.CommandText = SelectQry
            Return False
        End Try
        idx += 1
        cb.Dispose()
    Next
    'Put original select back for next call
    adapter.SelectCommand.CommandText = SelectQry
    Return True
End Function

我包括了我正在使用的两个例程。如果使用带分号的 select 调用,第一个例程将获得多个表。我传入表名数组以分配给每个表。如果数据集要更新到服务器,那么我还将传入主键和对适配器的引用以传递给更新调用。

我知道它是在 VB 而不是 C# 中,但我正在转换为 ASP.NET 的经典 ASP 已经在 VB 中,我不想在它之上移植到 C#。

更新代码为每个表的每个更新调用拆分选择字符串。

错误 - 上述代码不适用于所有表。对于一张表,如果我不接受更改,它将不会更新 - 出现并发错误。在另一张表上,它指出我在调用 acceptchanges 之前修改了 13 行 - 但在调用后变为零,因此没有更新记录。我的猜测是,为一个出现并发错误的表生成的更新 SQL 是废话,不应该调用 acceptchanges。当我解决这个问题时,我会更新帖子。

于 2017-01-21T23:36:56.400 回答
0

也许您可以使用事务?

SqlTransaction tr = conn.BeginTransaction();
    da = new SqlDataAdapter("select * from xxxx join.....", conn);
    builderForTable1 = new SqlCommandBuilder(da);
    da.Update(dataSetEmp, "Table");
    // ...
tr.Commit();

参考:

于 2013-04-25T15:45:20.147 回答