2013-04-25 60 views
0

我有一個包含兩個SQL表中的數據的數據集。如何用一個數據集更新兩個表格?

如何使用更新的數據集更新這兩個表? (因爲加入不工作)

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

回答

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"] 
) 
+0

如果你不返回多個結果集?因爲兩個表都在一個結果集中...... – Ruan 2013-04-25 15:45:59

+0

如果將兩個表連接到一個結果集中,那麼.net將會將其視爲一個結果集並僅加載一個表。如果你想加載兩個表,你需要提供兩個結果集或者使用一個datareader,並顯式地循環遍歷結果集,隨時填寫你的表。 (使用兩個結果集更容易,更清潔。) – 2013-04-25 15:50:55

+0

太棒了。乾淨的做法。謝謝 – Ruan 2013-04-25 16:03:56

0

也許你可以使用交易?

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

參考:

0
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 

我包括我使用這兩個程序。如果用分號選擇來調用第一個例程將獲得多個表。我傳遞表名數組以分配給每個表。如果數據集要更新到服務器,那麼我還傳入主鍵並引用適配器以傳遞到更新調用。

我知道它是在VB中,而不是C#,但我轉換到ASP.NET的經典ASP已經在VB中,我不想移植到C#上。

更新代碼爲每個表的每個更新調用拆分選擇字符串。

錯誤 - 上述代碼不適用於所有表格。對於一個表,如果我不做acceptchanges它不會更新 - 獲取併發性錯誤。在另一張桌子上,它表示在調用acceptchanges之前我有13個修改過的行 - 但是在調用之後它變爲零,因此沒有記錄被更新。我的猜測是,爲一個獲得併發錯誤的表生成的更新SQL是垃圾,並且acceptchanges不應該被調用。當我解決這個問題時,我會更新帖子。

相關問題