<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評(píng)論 :: 0 Trackbacks
    http://blog.csdn.net/jabby12/archive/2004/08/04/64027.aspx
    ADO.NET提供了Connection來(lái)連接數(shù)據(jù)庫(kù),同時(shí)也提供了Command對(duì)象來(lái)查詢數(shù)據(jù)庫(kù)。同Connection對(duì)象一樣,Command也有兩種:OleDbCommand和SqlCommand.其區(qū)別同Connection對(duì)象。

      要操縱數(shù)據(jù)庫(kù),必須先使用Connection來(lái)連接到數(shù)據(jù)庫(kù),再創(chuàng)建一個(gè)Command來(lái)查詢。有幾種創(chuàng)建方式,例:

    SqlCommand cmd;

    string strCon="server=localhost;database=Northwind;Trusted_Connection=Yes;";
    string strqry="select * from Categories";
    SqlConnection con=new SqlConnection(strCon);
    con.Open();
    1cmd=con.CreateCommand(); //這里使用用Connection對(duì)象的CreateCommand方法來(lái)創(chuàng)建一個(gè)Command對(duì)象。
    cmd.CommandText=strqry;
    //SqlDataReader reader=cmd.ExecuteReader();

    ?2cmd=new SqlCommand();?? //直接使用new 關(guān)鍵字來(lái)創(chuàng)建
    cmd.CommandText=strqry;
    ?cmd.Connection=con;
    ?? //設(shè)置與數(shù)據(jù)庫(kù)的連接

     3cmd=new SqlCommand(strqry,con); //直接在new的時(shí)候帶兩個(gè)參數(shù)來(lái)創(chuàng)建


     執(zhí)行方式:

    (主要有這么幾種,cmd.ExecuteReader();cmd.ExecuteNonQuery();cmd.ExecuteScalar();cmd.ExecuteXmlReader();)

     1,ExecuteReader();返回一個(gè)SqlDataReader對(duì)象或OleDbDataReader對(duì)象,這個(gè)看你的程序的需要去  做。可以通過(guò)這個(gè)對(duì)象來(lái)檢查查詢結(jié)果,它提供了“游水”式的執(zhí)行方式,即從結(jié)果中讀取一行之后,移動(dòng)到另一行,則前一行就無(wú)法再用。有一點(diǎn)要注意的是執(zhí)行之后,要等到手動(dòng)去調(diào)用Read()方法之后,DataReader對(duì)象才會(huì)移動(dòng)到結(jié)果集的第一行,同時(shí)此方法也返回一個(gè)Bool值,表明下一行是否可用,返回True則可用,返回False則到達(dá)結(jié)果集末尾。

    使用DataReader可以提高執(zhí)行效率,有兩種方式可以提高代碼的性能:一種是基于序號(hào)的查找,一個(gè)是使用適當(dāng)?shù)腉et方法來(lái)查找。因?yàn)椴樵兂鰜?lái)的結(jié)果一般都不會(huì)改變,除非再次改動(dòng)查詢語(yǔ)句,因此可以通過(guò)定位列的位置來(lái)查找記錄。用這種方法有一個(gè)問(wèn)題,就是可能知道一列的名稱而不知道其所在的位置,這個(gè)問(wèn)題的解決方案是通過(guò)調(diào)用DataReader 對(duì)象的GetOrdinal()方法,此方法接收一個(gè)列名并返回此列名所在的列號(hào)。例:

    int id=reader.GetOrdinal("CategoryName");
    while(reader.Read())
    {
    Response.Write(reader[id]);

    reader.Close();

    ?至于第二種方式很直觀,例:

     while(reader.Read())
    {
      ?Response.Write(reader.GetInt32(0).ToString()+" "+reader.GetString(1).ToString()+"
    ");
    }

     DataReader的GetInt32()和GetString()通過(guò)接收一個(gè)列號(hào)來(lái)返回一個(gè)列的值,這兩種是最常用的,其中  還有很多其它的類型。

    (注:DataReader對(duì)象在調(diào)用Close()方法即關(guān)閉與數(shù)據(jù)庫(kù)的連接,如果在沒(méi)有關(guān)閉之前又重新打開(kāi)第二個(gè)連接,則會(huì)產(chǎn)生一條異常信息)

     2.,ExecuteNonQuery()?這個(gè)方法并不返回一個(gè)DataReader對(duì)象,而是返回一個(gè)int類型的值,即在執(zhí)行之后在數(shù)據(jù)庫(kù)中所影響的行數(shù)。

     例:

     int affectrows=cmd.ExecuteNonQuery();
    Response.Write(affectrows +" 條記錄受影響");

    ?3,ExecuteScalar() 這個(gè)方法不接受任何參數(shù),僅僅返回查詢結(jié)果集中的第一行第一列,而忽略了其它的行和列,而且返回的是一個(gè)object類型,在使用之前必須先將它強(qiáng)制轉(zhuǎn)換為所需類型。如果返回的僅僅是一個(gè)單獨(dú)的數(shù)據(jù)元,則可以使用此方法來(lái)提高代碼的性能。例:

    string strCon="server=localhost;database=Northwind;Trusted_Connection=Yes;";
    string strqry="select count(*) from Categories";
    SqlConnection con=new SqlConnection(strCon);
    con.Open();
    SqlCommand cmd=con.CreateCommand();
    int i=Convert.ToInt32(cmd.ExecuteScalar()); //必須強(qiáng)制轉(zhuǎn)換

     4,ExecuteXmlReader() 此方法用于XML操作,返回一個(gè)XmlReader對(duì)象,由于系統(tǒng)默認(rèn)沒(méi)有引用 System.Xml名空間,因此在使用前必須前引入。例:

    string strCon="server=localhost;database=Northwind;Trusted_Connection=Yes;";
    SqlConnection con=new SqlConnection(strCon);
    con.Open();
    SqlCommand cmd = new SqlCommand("select * from Categories FOR XML AUTO, XMLDATA", con);
    XmlReader xr=cmd.ExecuteXmlReader();
    Response.Write(xr.AttributeCount);  //這里獲取當(dāng)前節(jié)點(diǎn)上的屬性個(gè)數(shù)
    ?

    xr.Close();

     執(zhí)行完畢之后,照樣要顯式地調(diào)用Close()方法,否則會(huì)拋出異常。

     使用參數(shù)化的查詢

      先看一段SQL語(yǔ)句:select CategoryID,Description from Categories where CategoryID=? 其中的問(wèn)號(hào)就是一個(gè)參數(shù)。但在使用的時(shí)候必須是帶有@前綴的命名參數(shù),因?yàn)?NET數(shù)據(jù)提供程序不支持這個(gè)通用的參數(shù)標(biāo)記“?”.使用參數(shù)化的查詢可以大大地簡(jiǎn)化編程,而且執(zhí)行效率也比直接查詢字符串要高,也更方便,很多情況下都需要更改查詢字符串,這種方式就提供了方便,只需更改參數(shù)的值即可。例:

     string strCon="server=localhost;database=Northwind;Trusted_Connection=Yes;";
    SqlConnection con=new SqlConnection(strCon);
    con.Open();
    string strqry="select * from Categories where CategoryID=@CategoryID"; //帶參數(shù)的查詢
    SqlCommand cmd=new SqlCommand(strqry,con);
    cmd.Parameters.Add("@CategoryID",SqlDbType.Int,4); //給參數(shù)賦于同數(shù)據(jù)庫(kù)中相同的類型
    cmd.Parameters["@CategoryID"].Value="3"; //給參數(shù)賦值,可靈活改變
    SqlDataReader r=cmd.ExecuteReader(); 
    while(r.Read())
    {
    Response.Write(r.GetString(2)+"
    "); //取出指定參數(shù)列的值
    }
    con.Close(); //切記關(guān)閉

     使用存儲(chǔ)過(guò)程進(jìn)行查詢

     先看段存儲(chǔ)過(guò)程的形式:create procedure cateproc (@CategoryID int(4)) as select * from Categories where CategoryID=@CategoryID? return。

     這個(gè)是數(shù)據(jù)庫(kù)中的存儲(chǔ)過(guò)程實(shí)現(xiàn)方式,要在程序中調(diào)用存儲(chǔ)過(guò)程,一種方法是使用Command對(duì)象的 CommandType屬性來(lái)實(shí)現(xiàn)。CommandType有三個(gè)枚舉值:Text,TableDirect,StoredProcedure。只需將CommandType屬性設(shè)為第三個(gè)值即可實(shí)現(xiàn)調(diào)用存儲(chǔ)過(guò)程。例:

     string strCon="server=localhost;database=Northwind;Trusted_Connection=Yes;";
    SqlConnection con=new SqlConnection(strCon);
    con.Open();
    SqlCommand cmd=con.CreateCommand();
    cmd.CommandText="cateproc";
    cmd.CommandType=CommandType.StoredProcedure;
    cmd.Parameters.Add("@CategoryID",SqlDbType.Int,4);
    cmd.Parameters["CategoryID"].Value="2";
    SqlDataReader r=cmd.ExecuteReader();
    while(r.Read())
    {
    Response.Write(r.GetString(2)+"
    ");
    }
    con.Close();

     其實(shí)在程序中實(shí)現(xiàn)調(diào)用存儲(chǔ)過(guò)程的方式跟參數(shù)化查詢很類似,有點(diǎn)舊鞋翻新的味道。

     cmd.CommandType=CommandType.StoredProcedure;這種方式有個(gè)缺點(diǎn),就是當(dāng)要查詢的表,視圖或存儲(chǔ)過(guò)程的名稱中有特殊的字符(如空格)的話,則將無(wú)法識(shí)別。因此還有一種方式就是:

     cmd.CommandText="{Call cateproc(?)}"; //這里是調(diào)用存儲(chǔ)過(guò)程,問(wèn)號(hào)為參數(shù)
    cmd.CommandType=CommandType.Text; //關(guān)鍵是這里。

     設(shè)置命令執(zhí)行超時(shí)

     命令超時(shí)是指Command對(duì)象在等待結(jié)果的時(shí)間,(默認(rèn)為30秒)如果在30秒內(nèi)沒(méi)執(zhí)行查詢,則Command拋出一個(gè)異常。也可以自己進(jìn)行設(shè)置。例:cmd.CommandTimeout=60;

     取消執(zhí)行查詢

     有時(shí)因某種原因,需要臨時(shí)取消命令的執(zhí)行,可調(diào)用Command對(duì)象的Cancel()方法來(lái)退出執(zhí)行,如果在未執(zhí)行查詢之前,Cancel()將不做任何事。


    首先,ADO.NET中使用了DataAdapter 來(lái)處理與數(shù)據(jù)庫(kù)的聯(lián)機(jī)與脫機(jī)。當(dāng)時(shí)開(kāi)發(fā)人員設(shè)計(jì)了DataAdapter是為了能夠處理脫機(jī)數(shù)據(jù),方便操作,關(guān)于這一點(diǎn),只要調(diào)用其Fill()方法即可,這時(shí)會(huì)在DataSet中創(chuàng)建一個(gè)新的名為“Table“的DataTable.要重新指定名可用DataAdapter.Fill(DataSet,“Tabelname“)。此時(shí)connection也關(guān)閉了。DataAdapter既可以用來(lái)提交查詢,并將結(jié)果存儲(chǔ)到DataSet中,也可以用來(lái)向數(shù)據(jù)庫(kù)傳遞更改。僅僅使用其Update方法即可達(dá)到向數(shù)據(jù)庫(kù)提交存儲(chǔ)地DatSet中的更改。

        DataAdapter將查詢的結(jié)果存儲(chǔ)在DataSet或DataTable對(duì)象中,當(dāng)執(zhí)行這一過(guò)程的時(shí)候,DataAdapter使用了一個(gè)Command來(lái)與數(shù)據(jù)庫(kù)通訊,并在內(nèi)部使用了DataReader來(lái)獲取查詢結(jié)果,最后才將結(jié)果復(fù)制到DataSet新行中去。這也是Fill的過(guò)程。如果有兩個(gè)DataAdapter對(duì)象,都使用相同的Connection對(duì)象,在創(chuàng)建的時(shí)候就會(huì)創(chuàng)建兩個(gè)Connection對(duì)象,而不是同一個(gè),這種情況的解決方案是:


       SqlConnection con=new SqlConnection("server=localhost;database=Northwind;Trusted_Connection=Yes;")
       SqlDataAdapter da=new SqlDataAdapter("select CategoryID,Description from Categories",con);
       SqlDataAdapter da=new SqlDataAdapter("select CategoryID,Description from Customers",con);

    而不是將查詢字符串,單獨(dú)寫(xiě)成一行。

       有時(shí)候可能并不希望DataSet中的架構(gòu)與數(shù)據(jù)庫(kù)中的架構(gòu)相同,這種情況的解決方案之一是可以采用別名的方法,即select id as Product ID,amount as Product Amount from product;另外一種解決方案就是使用DataAdapter提供的TableMappings集合機(jī)制,通過(guò)它就可以將查詢結(jié)果映射到DataSet結(jié)構(gòu)中,這種方法更方便,更靈活。TableMappings屬性返回一個(gè)DataTableMappingsCollection對(duì)象,其中包含了一組DataTableMappings,只要DataSet中相應(yīng)的表名稱與數(shù)據(jù)庫(kù)中的表名相同,即可以使用它來(lái)創(chuàng)建一個(gè)映射(DataSet中可以有多個(gè)表)。TableMappings里還有一個(gè)ColumnMappings屬性,其用法與TableMappings相似。其原理是DataAdapter從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)后,利用DataReader從結(jié)果集中獲取列名稱,有一點(diǎn)特別要注意,即只能獲取列名稱而無(wú)法獲取表名稱,DataAdapter事先假定表名稱為T(mén)able,接著遇到映射語(yǔ)句則進(jìn)行表映射。不說(shuō)了,看代碼:

      DataColumnMapping colMap;
       SqlConnection con=new SqlConnection("server=localhost;database=Northwind;Trusted_Connection=Yes;");
       SqlDataAdapter da=new SqlDataAdapter("select CategoryID,Description from Categories",con);
       DataSet ds=new DataSet();

       DataTableMapping tblMap=da.TableMappings.Add("Table","Ca"); //這里Table為關(guān)鍵,映射表名為Ca

       colMap=tblMap.ColumnMappings.Add("CategoryID","ID"); //映射列表
       colMap=tblMap.ColumnMappings.Add("Description","描述");
       // Response.Write(tblMap.DataSetTable.ToString());
        da.Fill(ds);
       DataTable dt=ds.Tables["Ca"]; //這里是映射后的表名,如果仍為數(shù)據(jù)庫(kù)的表名,則無(wú)效,特別注意
       this.DataGrid1.DataSource=dt;
       this.DataGrid1.DataBind();

    運(yùn)行代碼后就會(huì)發(fā)現(xiàn)DataGrid1上的列名為ID和描述 (^_^)

    (注:使用DataTableMapping 之前要前導(dǎo)入名空間System.Data.Common;)

    還可以使用AddRange方法來(lái)簡(jiǎn)化表和列的映射:(一些代碼同上面)

      .......                
       DataTableMapping tblMap=da.TableMappings.Add("Table","Ca");       DataColumnMapping[] colMapArray=new DataColumnMapping[]{new DataColumnMapping("CategoryID","產(chǎn)   品號(hào)"),new DataColumnMapping("Description","描述")};        tblMap.ColumnMappings.AddRange(colMapArray);     
       ......                  

    這種映射關(guān)系只能從數(shù)據(jù)庫(kù)中讀取展示給用戶,如果要將映射后的Table的更改提交給數(shù)據(jù)庫(kù),這時(shí)庫(kù)發(fā)現(xiàn)其中列與庫(kù)中列不同,便會(huì)發(fā)生異常,DataAdapter 同時(shí)也提供了MissingMappingAction屬性來(lái)處理。

    DataAdapter1.MissingMappingAction=MissingMappingAction.Passthrough/Ignore/Error

    它接受MissingMappingAction的枚舉值,Passthrough這個(gè)值表示如果在庫(kù)中找不到與DataSet中相同列的話,就將此列映射到庫(kù)中,Ignore枚舉值表示忽略示出現(xiàn)的列,Error表示找不到相應(yīng)的列則拋出異常。

    分頁(yè):

    分頁(yè)在應(yīng)用中是常有的事,而DataAdapter本身也提供了分頁(yè)的簡(jiǎn)單功能,如:DataAdapter1.Fill(dataset,startrow,rownum,“tablename“)這種功能用于數(shù)據(jù)量較小的查詢就可以,但當(dāng)有大量數(shù)據(jù)的時(shí)候,就會(huì)發(fā)現(xiàn)這種分頁(yè)的問(wèn)題的存在。它的原理是假如有一百行數(shù)據(jù),分成十頁(yè),每頁(yè)十行,當(dāng)獲取每一頁(yè)的時(shí)候,返回前10行,再接著,第二頁(yè),刪除了前10行而獲取接下的10行,在這一次中,只是為了獲取10行數(shù)據(jù),但數(shù)據(jù)庫(kù)卻返回了20行,依此類推,第10頁(yè)的時(shí)候就會(huì)返回100行,而DataAdapter本身就幫我們刪除了90行,因?yàn)槲覀兛瓷先シ祷氐倪€是10行,這種性能太低。因此本篇繼續(xù)介紹另外一種性能較高的分頁(yè)方法。實(shí)際上這種分頁(yè)方法是將上一頁(yè)最后一行的鍵值存儲(chǔ)下來(lái),直接在SQL語(yǔ)句中就過(guò)濾掉了,不象前面那種到DataAdapter這邊才過(guò)濾掉。例:

    con=new SqlConnection("server=localhost;database=Northwind;Trusted_Connection=Yes;");
    da=new SqlDataAdapter("select top 50 CustomerID,CompanyName from Customers where CustomerID>'BOTTM'",con); 
    ds=new DataSet();
    da.Fill(ds,"Categories");
    this.DataGrid1.DataSource=ds.Tables["Categories"]; this.DataGrid1.DataBind();
    con.Close();

    這里假如上一頁(yè)最后一個(gè)鍵值為”BOTTM”,可以將它用參數(shù)替代掉,這樣就查出了在'BOTTM'之后的50行。這種方法實(shí)現(xiàn)簡(jiǎn)單效率也高。

    posted on 2005-04-12 13:52 笨笨 閱讀(563) 評(píng)論(0)  編輯  收藏 所屬分類: ALL.NET
    主站蜘蛛池模板: 亚洲产国偷V产偷V自拍色戒| 大地资源网高清在线观看免费| 亚洲国产精品线在线观看| 成人免费无码精品国产电影| 久久久久av无码免费网| a级午夜毛片免费一区二区| 亚洲a∨国产av综合av下载| 亚洲娇小性色xxxx| 久久亚洲日韩精品一区二区三区| 亚洲国产成人a精品不卡在线| 91成人免费在线视频| 无码一区二区三区免费| 中文字幕免费播放| 免费无码婬片aaa直播表情| 亚洲精品无码专区在线| 亚洲精品亚洲人成在线播放| 亚洲欧洲精品国产区| 亚洲综合久久1区2区3区| 亚洲国产成人高清在线观看| 中文字幕中韩乱码亚洲大片| 啦啦啦在线免费视频| 免费毛片a线观看| a级毛片毛片免费观看永久| japanese色国产在线看免费| 污污污视频在线免费观看| 女bbbbxxxx另类亚洲| 国产大陆亚洲精品国产| 亚洲第一se情网站| 噜噜噜亚洲色成人网站| 在线观看亚洲免费视频| 特级无码毛片免费视频| 免费播放美女一级毛片| 免费看一级高潮毛片| 欧洲精品码一区二区三区免费看| 色www免费视频| 成人免费网站视频www| 国产精品免费观看视频| 日韩免费高清播放器| 西西人体免费视频| 污视频在线免费观看| 国产h肉在线视频免费观看|