1:自動生成命令的條件 CommandBuilder 方法
a)動態指定 SelectCommand 屬性
b)利用 CommandBuilder 對象自動生成 DataAdapter 的 DeleteCommand、InsertCommand 和 UpdateCommand。
c)為了返回構造 INSERT、UPDATE 和 DELETE 。SQL CommandBuilder 必須執行 SelectCommand。
即:必須額外經歷一次到數據源的行程,這可能會降低性能。這也是
自動生成命令的缺點。
d)SelectCommand 還必須返回至少一個主鍵或唯一列.
當CommandBuilder和DataAdapter關聯時,就會自動生成DeleteCommand、
InsertCommand 和 UpdateCommand中為空的命令。即不空的不生成。
e)必須是一個表,SELECT的不能是多個表的聯合。
#動生成命令的規則#
在數據源處為表中所有 RowState 為 Added 的行插入一行(不包括標識、表達式或時間戳等列)。
為 Modified 的行更新行(列值匹配行的主鍵列值) 。
Deleted 的行刪除行(列值匹配行的主鍵列值).這就是為什麼要求條件c.d
注意:
a)因為從SELECT數據到UPDATE數據,中間這段時間有可能別的用戶已經對數據進行了修改。
自動生成命令這種UPDATE只對在行包含所有原始值並且尚未從數據源中刪除時更新。
b)自動命令生成邏輯為獨立表生成 INSERT、UPDATE 或 DELETE 語句,
而不考慮與數據源中其他表的任何關系。因此,當調用 Update
來為參與數據庫中外鍵約束的列提交更改時,可能會失敗。若要避免這一異常,
請不要使用 CommandBuilder 來更新參與外鍵約束的列,而應顯式地指定用於執行該操作的語句。
下面是自動生成命令的例子
// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
DataSet custDS = new DataSet();
connection.Open();
adapter.Fill(custDS, "Customers");
// Code to modify data in the DataSet here.
// Without the SqlCommandBuilder, this line would fail.
adapter.Update(custDS, "Customers");
connection.Close();
2:使用 DataAdapter 更新數據源
注意:
a)如果 SelectCommand 返回 OUTER JOIN 的結果,則 DataAdapter
不會為生成的 DataTable 設置 PrimaryKey 值。您必須自己定義
PrimaryKey 以確保正確解析重復行.
b)如果對 DataSet、DataTable 或 DataRow 調用 AcceptChanges,
則將使 DataRow 的所有 Original 值都將被重寫為該 DataRow 的 Current 值。
如果已修改將該行標識為唯一行的字段值,那麼當調用 AcceptChanges 後,
Original 值將不再匹配數據源中的值。
下面例子
// Assumes connection is a valid SqlConnection.
SqlDataAdapter dataAdpater = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM Categories", connection);
dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = @CategoryName " +
"WHERE CategoryID = @CategoryID" , connection);
dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID";
parameter.SourceVersion = DataRowVersion.Original;
DataSet dataSet = new DataSet();
dataAdpater.Fill(dataSet, "Categories");
DataRow row = dataSet.Tables["Categories"].Rows[0];
row ["CategoryName"] = "New Category";
dataAdpater.Update(dataSet, "Categories");
------------------------------------------------------------------------------------------------
插入、更新和刪除的排序
在許多情況下,以何種順序向數據源發送通過 DataSet 作出的更改是相當重要的。
例如,如果已更新現有行的主鍵值並且添加了具有新主鍵值的新行,
則務必要在處理插入之前處理更新。
可以使用 DataTable 的 Select 方法來返回僅引用具有特定 RowState 的 DataRow 數組。
然後可以將返回的 DataRow 數組傳遞到 DataAdapter 的 Update 方法來處理已修改的行。
通過指定要更新的行的子集,可以控制處理插入、更新和刪除的順序。
DataTable table = dataSet.Tables["Customers"];
// First process deletes.
adapter.Update(table.Select(null, null, DataViewRowState.Deleted));
// Next process updates.
adapter.Update(table.Select(null, null,
DataViewRowState.ModifiedCurrent));
// Finally, process inserts.
adapter.Update(table.Select(null, null, DataViewRowState.Added));
3.使用sql語句更新
例如:
cmd = new OleDbCommand(string.Format(@"insert into worker(workerid,workername,password,phoneno) values ('{0}','{1}','{2}','{3}') ", textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text),oc);
oc.Open();
try
{
int i = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
}
性能的優劣及使用的情形,還未完全明白。
一般的,綁定bindingsource,用datatable綁定bindingsource (實質上綁定的是datatable。defaultview,同時可用到dataview的篩選功能,但但在篩選完後,filter要重置為null,否則出現的一直是經過篩選的數據)詳見bindingsource 文章
其他:
1.使用builder 的作用:
OleDbCommandBuilder cb = new OleDbCommandBuilder(da);
這個主要是為了讓C#自動為OleDbDataAdapter da生成相對應的DeleteCommand,UpdateCommand!
你可以把DataTable和DataSet看做是數據容器,比如你查詢數據庫後得到一些結果,可以放到這種容器裡,那你可能要問:我不用這種容器,自己讀到變量或數組裡也一樣可以存起來啊,為什麼用容器?
原因是,這種容器的功能比較強大,除了可以存數據,還可以有更大用途。舉例:在一個c/s結構的桌面數據庫系統裡,你可以把前面存放查詢結果的容器裡的數據顯示到你客戶端界面上,用戶在界面上對數據進行添加、刪除、修改,你可以把用戶的操作更新到容器,等用戶操作完畢了,要求更新,然後你才把容器整個的數據變化更新到中心數據庫,這樣做的好處是什麼?就是減少了數據庫操作,客戶端速度提高了,數據庫壓力減小了。
DataSet可以比作一個內存中的數據庫,DataTable是一個內存中的數據表,DataSet裡可以存儲多個DataTable
With strBldSQL
.Append(" SELECT Jyuuyoudo_Code,detail FROM")
.Append(" SELECT * FROM")
.Append(" MASTER_IMPORT")
.Append(" ORDER BY B_ID ")
strSQLStmt = ""
strSQLStmt = strBldSQL.ToString
End With
' dataset作成
objDataset = dbconn.RunSelect(strSQLStmt)
' dataset
If objDataset.Tables("test").Rows.Count = 0 Then
MessageBox.Show("select is err!")
Else
End If
Me.Dgv_Jyuuyoudo.AutoGenerateColumns = False
Me.Dgv_Jyuuyoudo.DataSource = objDataset.Tables("test")
ds = CType(Me.Dgv_Jyuuyoudo.DataSource, DataTable)
數據庫類:
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Sql
Public Class DBAdpClass_chiyy
Private cnn As New SqlConnection
'select home定義一個dataset
Public Function RunSelect(ByVal sql As String) As DataSet
Dim cmd As SqlCommand
Dim da As SqlDataAdapter
Dim ds As New DataSet
cmd = New SqlCommand(sql, cnn)
If cnn.State = ConnectionState.Closed Then
cnn.Open()
End If
da = New SqlDataAdapter(cmd)
da.Fill(ds, "test")
Return ds
End Function