天天看點

使用DataSet Datatable 更新資料庫的三種方式

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 文章

其他: