日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

SqlDataAdapter.Update批量数据更新

發(fā)布時(shí)間:2024/4/17 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SqlDataAdapter.Update批量数据更新 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
SqlDataAdapter.Update批量數(shù)據(jù)更新

使用SqlDataAdapter.Update可以方便地對(duì)數(shù)據(jù)庫(kù)進(jìn)行快速、批量數(shù)據(jù)更新。我們最常用的多條數(shù)據(jù)更新方法是使用循環(huán)多次執(zhí)行SQL語(yǔ)句或存儲(chǔ)過程,這樣雖然方便,但由于連接和數(shù)據(jù)傳遞要在服務(wù)器和客戶端多次來(lái)往,大大增加了整個(gè)過程的時(shí)間,當(dāng)數(shù)據(jù)越大時(shí)越明顯!

下面對(duì)SqlDataAdapter.Update作個(gè)簡(jiǎn)單的演示介紹吧。

測(cè)試環(huán)境:SqlServer2008+VS2010+WinXP

1.建立測(cè)試數(shù)據(jù)庫(kù)和表

CREATE DATABASE [TEST]
GO

USE [Test]
GO

CREATE TABLE [Student](
?? ?[SNo] [int] NOT NULL,
?? ?[SName] [nvarchar](50) ,
?? ?[SAge] [int]
) O
GO

2.建立解決方案和項(xiàng)目

使用SqlDataAdapter.Update更新有三種方式,即SqlCommandBuiler自動(dòng)生成更新,使用配置數(shù)據(jù)源方式更新,手動(dòng)編寫命令。

SqlCommandBuiler方式:

代碼1:

?private void Form1_Load(object sender, EventArgs e)
??????? {
??????????? string constr = "server=localhost\\sqlserver2008;initial catalog=test;uid=sa;pwd=123456;";
??????????? SqlConnection conn = new SqlConnection(constr);
??????????? //設(shè)置select查詢命令,SqlCommandBuilder要求至少有select命令
??????????? SqlCommand selectCMD = new SqlCommand("select top 0 SNo,SName,SAge from Student", conn);
??????????? DataTable dt = new DataTable();
??????????? SqlDataAdapter sda = new SqlDataAdapter(selectCMD);
??????????? //上面的語(yǔ)句中使用select 0,不是為了查詢出數(shù)據(jù),而是要查詢出表結(jié)構(gòu)以向DataTable中填充表結(jié)構(gòu)
??????????? sda.Fill(dt);
??????????? //給DataTable添加10條記錄
??????????? for(int i=1;i<=10;i++)
??????????? dt.Rows.Add(new object[] { i, "aaa"+i, 20+i });
??????????? SqlCommandBuilder scb = new SqlCommandBuilder(sda);
??????????? //執(zhí)行更新
??????????? sda.Update(dt.GetChanges());
??????????? //使DataTable保存更新
??????????? dt.AcceptChanges();
?????????? ?
??????? }

?

//執(zhí)行后查看表中數(shù)據(jù),如圖:


上面我只作了插入操作,那現(xiàn)在將Select中的Top 0 去掉,把表中的數(shù)據(jù)全部加載到DataTable然后執(zhí)行刪除和更新操作

代碼2

??private void Form1_Load(object sender, EventArgs e)
??????? {

??? string constr = "server=localhost\\sqlserver2008;initial catalog=test;uid=sa;pwd=123456;";
??????????? SqlConnection conn = new SqlConnection(constr);
??????????? //設(shè)置select查詢命令,SqlCommandBuilder要求至少有select命令
??????????? SqlCommand selectCMD = new SqlCommand("select? SNo,SName,SAge from Student", conn);
??????????? DataTable dt = new DataTable();
??????????? SqlDataAdapter sda = new SqlDataAdapter(selectCMD);
??????????? //上面的語(yǔ)句中使用select 0,不是為了查詢出數(shù)據(jù),而是要查詢出表結(jié)構(gòu)以向DataTable中填充表結(jié)構(gòu)
??????????? sda.Fill(dt);
??????????? //先更新第1,2條數(shù)據(jù)的SName和SAge
??????????? dt.Rows[0]["SName"] = "AAA";
??????????? dt.Rows[0]["SAge"] = 33;
??????????? dt.Rows[1]["SName"] = "BBB";
??????????? dt.Rows[1]["SAge"] = 444;
??????????? //然后使用RemoveAt刪除第3,4條數(shù)據(jù)
??????????? dt.Rows.RemoveAt(2);
??????????? dt.Rows.RemoveAt(3);
??????????? //使用Delete刪除
??????????? //dt.Rows[2].Delete();
??????????? //dt.Rows[3].Delete();
??????????? SqlCommandBuilder scb = new SqlCommandBuilder(sda);
??????????? //執(zhí)行更新
??????????? sda.Update(dt.GetChanges());
??????????? //使DataTable保存更新
??????????? dt.AcceptChanges();

}

執(zhí)行后將出錯(cuò),錯(cuò)誤信息“對(duì)于不返回任何鍵列信息的 SelectCommand,不支持 UpdateCommand 的動(dòng)態(tài) SQL 生成。”

出錯(cuò)原因是建表時(shí)沒有設(shè)置主鍵。主鍵唯一標(biāo)識(shí)一行數(shù)據(jù),SqlCommandBuilder是根據(jù)DataTable每行的RowState及對(duì)應(yīng)的主鍵來(lái)生成命令的,沒有主鍵就無(wú)法確定刪除哪條數(shù)據(jù),當(dāng)然不可能根據(jù)其他列來(lái)刪除,因?yàn)槠渌锌赡苤貜?fù),這樣會(huì)刪除多行數(shù)據(jù),很可能執(zhí)行后不是你想要的結(jié)果,這種不確定性的對(duì)數(shù)據(jù)的操作方法,微軟當(dāng)然不可能提供給你!

那就給表添加主鍵吧

執(zhí)行如下SQL語(yǔ)句:
alter table student
add constraint PK_Student
primary key(SNo)

?再次執(zhí)行上面的代碼2.

執(zhí)行后


我們發(fā)現(xiàn)第1,2行數(shù)據(jù)更新了,但是第3,4行卻沒有刪除。這是怎么回事呢?

先不急,把代碼2中的

?dt.Rows.RemoveAt(2);
? dt.Rows.RemoveAt(3);

注釋掉,同時(shí)把

?//dt.Rows[2].Delete();
?? //dt.Rows[3].Delete();

的注釋去掉,使之執(zhí)行Delete方法而不是RemoveAt方法

再看看結(jié)果:

第3,4行已經(jīng)刪除。

原因是:使用RemoveAt或Remove會(huì)將數(shù)據(jù)真正的從DataTable中刪除,而使用Delete則不會(huì),而僅是把當(dāng)前行的RowState值置為deleted.

前面說(shuō)過SqlCommandBuilder是根據(jù)RowState和主鍵來(lái)生成命令的,RemoveAt/Remove把數(shù)據(jù)刪除了,怎么能找到主鍵和RowState呢?

所以使用SqlCommandBuilder時(shí)應(yīng)該注意的2點(diǎn):表要有主鍵,應(yīng)使用delete方法刪除行.

手寫命令方法:

代碼3:

??private void Form1_Load(object sender, EventArgs e)
??????? {
??????????? string constr = "server=localhost\\sqlserver2008;initial catalog=test;uid=sa;pwd=123456;";
??????????? SqlConnection conn = new SqlConnection(constr);
??????????? //設(shè)置select查詢命令
??????????? SqlCommand selectCMD = new SqlCommand("select? SNo,SName,SAge from Student", conn);
??????????? //Insert命令
??????????? SqlCommand insertCMD = new SqlCommand("insert into Student(SNo,SName,SAge) values(@SNo,@SName,@SAge)", conn);
??????????? //Update命令
??????????? SqlCommand updateCMD = new SqlCommand("update Student Set SName=@SName,SAge=@SAge where SNo=@SNo", conn);
??????????? //Delete命令
??????????? SqlCommand deleteCMD = new SqlCommand("delete from Student where SNo=@SNo", conn);

??????????? //給Insert,Update,Delete三個(gè)命令添加參數(shù)
??????????? SqlParameter paraSNo1, paraSNo2, paraSNo3;//第二個(gè)指定參數(shù)值的來(lái)源,這里的SNo是指DataTable中的列名
??????????? paraSNo1 = new SqlParameter("@SNo", "SNo");
??????????? paraSNo2 = new SqlParameter("@SNo", "SNo");
??????????? paraSNo3 = new SqlParameter("@SNo", "SNo");
??????????? paraSNo1.SourceVersion = DataRowVersion.Current;//指定SourceVersion確定參數(shù)值是列的當(dāng)前值(Current),還是原始值(Original),還是建議值(Proposed)
??????????? paraSNo2.SourceVersion = DataRowVersion.Current;
??????????? paraSNo3.SourceVersion = DataRowVersion.Current;

??????????? SqlParameter paraSName1, paraSName2, paraSName3;
??????????? paraSName1 =? new SqlParameter("@SName", "SName");
??????????? paraSName2 = new SqlParameter("@SName", "SName");
??????????? paraSName3 = new SqlParameter("@SName", "SName");
??????????? paraSName1.SourceVersion = DataRowVersion.Current;
??????????? paraSName2.SourceVersion = DataRowVersion.Current;
??????????? paraSName3.SourceVersion = DataRowVersion.Current;

??????????? SqlParameter paraSAge1, paraSAge2, paraSAge3;
??????????? paraSAge1 = new SqlParameter("@SAge", "SAge");
??????????? paraSAge2 = new SqlParameter("@SAge", "SAge");
??????????? paraSAge3 = new SqlParameter("@SAge", "SAge");
??????????? paraSAge1.SourceVersion = DataRowVersion.Current;
??????????? paraSAge2.SourceVersion = DataRowVersion.Current;
??????????? paraSAge3.SourceVersion = DataRowVersion.Current;

??????????? insertCMD.Parameters.AddRange(new SqlParameter[] { paraSNo1, paraSName1, paraSAge1 });
??????????? updateCMD.Parameters.AddRange(new SqlParameter[] { paraSNo2, paraSName2, paraSAge2 });
??????????? deleteCMD.Parameters.AddRange(new SqlParameter[] { paraSNo3, paraSName3, paraSAge3 });

??????????? DataTable dt = new DataTable();
??????????? SqlDataAdapter sda = new SqlDataAdapter(selectCMD);
??????????? sda.Fill(dt);
??????????? //插入2條數(shù)據(jù)
??????????? dt.Rows.Add(new object[] { 11, "aa11", 31 });
??????????? dt.Rows.Add(new object[] { 12, "aa12", 32 });


??????????? //先更新第1,2條數(shù)據(jù)的SName和SAge
??????????? dt.Rows[0]["SName"] = "CCC";
??????????? dt.Rows[0]["SAge"] = 55;
??????????? dt.Rows[1]["SName"] = "DDD";
??????????? dt.Rows[1]["SAge"] = 66;

??????????? //使用Delete刪除第3,4條數(shù)據(jù)
??????????? dt.Rows[2].Delete();
??????????? dt.Rows[3].Delete();
??????????? SqlCommandBuilder scb = new SqlCommandBuilder(sda);
??????????? //執(zhí)行更新
??????????? sda.Update(dt.GetChanges());
??????????? //使DataTable保存更新
??????????? dt.AcceptChanges();
??????? }

執(zhí)行結(jié)果:

可以看到

第SNo為11,12的數(shù)據(jù)是新增的。

原來(lái)SNo為1,2的數(shù)據(jù)中SName已經(jīng)從AA,BB更改為CC,DD,另一列SAge從33,44更改為55,66。

原來(lái)SNo為5,6也就是第3,4條數(shù)據(jù)已經(jīng)被刪除

轉(zhuǎn)載于:https://www.cnblogs.com/andylaufzf/archive/2011/11/10/2244499.html

總結(jié)

以上是生活随笔為你收集整理的SqlDataAdapter.Update批量数据更新的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。