我有一個包含兩個SQL表中的數據的數據集。如何用一個數據集更新兩個表格?
如何使用更新的數據集更新這兩個表? (因爲加入不工作)
da = new SqlDataAdapter("select * from xxxx join.....", conn);
builderForTable1 = new SqlCommandBuilder(da);
da.Update(dataSetEmp, "Table");
我有一個包含兩個SQL表中的數據的數據集。如何用一個數據集更新兩個表格?
如何使用更新的數據集更新這兩個表? (因爲加入不工作)
da = new SqlDataAdapter("select * from xxxx join.....", conn);
builderForTable1 = new SqlCommandBuilder(da);
da.Update(dataSetEmp, "Table");
的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"]
)
也許你可以使用交易?
SqlTransaction tr = conn.BeginTransaction();
da = new SqlDataAdapter("select * from xxxx join.....", conn);
builderForTable1 = new SqlCommandBuilder(da);
da.Update(dataSetEmp, "Table");
// ...
tr.Commit();
參考:
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不應該被調用。當我解決這個問題時,我會更新帖子。
如果你不返回多個結果集?因爲兩個表都在一個結果集中...... – Ruan 2013-04-25 15:45:59
如果將兩個表連接到一個結果集中,那麼.net將會將其視爲一個結果集並僅加載一個表。如果你想加載兩個表,你需要提供兩個結果集或者使用一個datareader,並顯式地循環遍歷結果集,隨時填寫你的表。 (使用兩個結果集更容易,更清潔。) – 2013-04-25 15:50:55
太棒了。乾淨的做法。謝謝 – Ruan 2013-04-25 16:03:56