(一)淺談?dòng)螛?biāo)

      1)游標(biāo)的概念

      游標(biāo)是指向查詢結(jié)果集的一個(gè)指針,它是一個(gè)通過(guò)定義語(yǔ)句與一條Select語(yǔ)句相關(guān)聯(lián)的一組SQL語(yǔ)句,即從結(jié)果集中逐一的讀取一條記錄。游標(biāo)包含兩方面的內(nèi)容:

       ●游標(biāo)結(jié)果集:執(zhí)行其中的Select語(yǔ)句所得到的結(jié)果集;

       ●游標(biāo)位置:一個(gè)指向游標(biāo)結(jié)果集內(nèi)的某一條記錄的指針

       利用游標(biāo)可以單獨(dú)操縱結(jié)果集中的每一行。游標(biāo)在定義以后存在兩種狀態(tài):關(guān)閉和打開(kāi)。當(dāng)游標(biāo)關(guān)閉時(shí),其查詢結(jié)果集不存在;只有當(dāng)游標(biāo)打開(kāi)時(shí),才能按行讀取或修改結(jié)果集中的數(shù)據(jù)。

    (2)淺談?dòng)螛?biāo)

         游標(biāo)我們可以通俗的解釋為變動(dòng)的標(biāo)示。正如它的解釋一樣,數(shù)據(jù)庫(kù)中的游標(biāo)其實(shí)也是一種讀取數(shù)據(jù)的方式。舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō):我有一個(gè)電話本,電話本上的號(hào)碼首先是按地域劃分的,現(xiàn)在我想找個(gè)家住廊坊的李四。首先我們要做的是先找到廊坊地區(qū)的電話表,找到后的表也即是我們上面所說(shuō)的游標(biāo)結(jié)果集;而為了找到李四我們可能會(huì)用手一條一條逐行的掃過(guò),以幫助我們找到所需的那條記錄。對(duì)應(yīng)于數(shù)據(jù)庫(kù)來(lái)說(shuō),這就是游標(biāo)的模型。所以,你可以這樣想象:表格是數(shù)據(jù)庫(kù)中的表,而我們的手好比是游標(biāo)。

       總結(jié)來(lái)說(shuō)游標(biāo)就好比是在電話本上逐一掃描號(hào)碼的手指。

(二)使用游標(biāo)

       一個(gè)應(yīng)用程序中可以使用兩種類型的游標(biāo):前端(客戶)游標(biāo)和后端(服務(wù)器)游標(biāo),它們是兩個(gè)不同的概念。

       但無(wú)論使用哪種游標(biāo),都必須經(jīng)過(guò)如下的步驟:

       ●聲明游標(biāo)

       ●打開(kāi)游標(biāo)

       ●從游標(biāo)中操作數(shù)據(jù)

       ●關(guān)閉游標(biāo)

      下面我們主要講述下服務(wù)器游標(biāo):

      1)定義游標(biāo)

         使用游標(biāo)之前必須先聲明它。聲明指定定義游標(biāo)結(jié)果集的查詢。通過(guò)使用for updatefor read only關(guān)鍵詞將游標(biāo)顯式定義成可更新的或只讀的。

      Declare cursor_name  cursor

     For select_statement

     [for{read only|update[of colum_name_list]}]

      舉例:

      Declare  company_crsr cursor

      For select name,salary from company where salary>2000

      For update of name,salary

      上面我們聲明了一個(gè)名為company_crsr的游標(biāo)。

      2)打開(kāi)游標(biāo)

         open的語(yǔ)法為:

                         open 游標(biāo)名

        在聲明游標(biāo)后,必須打開(kāi)它以便用fetch,update,delete讀取、修改、刪除行。在打開(kāi)一個(gè)游標(biāo)后,它將被放在游標(biāo)結(jié)果集的首行前,必須用fetch語(yǔ)句訪問(wèn)該首行。

      3)讀取游標(biāo)數(shù)據(jù)

      在聲明并打開(kāi)一個(gè)游標(biāo)后,可用fetch命令從游標(biāo)結(jié)果集中獲取數(shù)據(jù)行。

      Fetch的語(yǔ)法為:

           Fetch [[Next | Prior | First | Last | Absolute{n|@nvar} |Relative {n|@nvar}]

         From]  游標(biāo)名 [into 變量列表]

      參數(shù)說(shuō)明:

      Next:返回結(jié)果集中當(dāng)前行的下一行,如果該語(yǔ)句是第一次讀取結(jié)果集中數(shù)據(jù)則返回的是第一行

      Prior:返回結(jié)果集中當(dāng)前行的上一行,如果該語(yǔ)句是第一次讀取結(jié)果集中的數(shù)據(jù)則無(wú)記錄結(jié)果返回并把游標(biāo)位置設(shè)置為第一行。

      First:返回游標(biāo)第一行;Last:返回游標(biāo)中的最后一行;

      Absolute{n|@nvar}:如果 n  @nvar 為正數(shù),返回從游標(biāo)頭開(kāi)始的第 n 行并將返回的行變成新的當(dāng)前行。如果 n  @nvar 為負(fù)數(shù),返回游標(biāo)尾之前的第 n 行并將返回的行變成新的當(dāng)前行。如果 n  @nvar  0,則沒(méi)有行返回。必須為整型常量且 @nvar 必須為smallinttinyint  int

      RELATIVE {n | @nvar}:如果 n  @nvar 為正數(shù),返回當(dāng)前行之后的第 n 行并將返回的行變成新的當(dāng)前行。如果 n  @nvar 為負(fù)數(shù),返回當(dāng)前行之前的第 n 行并將返回的行變成新的當(dāng)前行。如果 n  @nvar  0,返回當(dāng)前行。如果對(duì)游標(biāo)的第一次提取操作時(shí)將FETCH RELATIVE  n  @nvar 指定為負(fù)數(shù)或 0,則沒(méi)有行返回。必須為整型常量且@nvar 必須為 smallinttinyint  int

      舉例:

       Fetch  next

       company_crsr into @name,@salary

      SQL Server在每次讀取后返回一個(gè)狀態(tài)值。可用@@sql_status訪問(wèn)該值,下表給出了可能的@@sql_status值及其意義。

    值意義:

             0——Fetch語(yǔ)句成功

             1——Fetch語(yǔ)句導(dǎo)致一錯(cuò)誤

             2——結(jié)果集沒(méi)有更多的數(shù)據(jù),當(dāng)前位置位于結(jié)果集最后一行,而客戶對(duì)該游標(biāo)仍發(fā)出Fetch語(yǔ)句時(shí)。

     若游標(biāo)是可更新的,可用updatedelete語(yǔ)句來(lái)更新和刪除行。

     刪除游標(biāo)當(dāng)前行的語(yǔ)法為:

                      Delete [from] 表名

                      where current of 游標(biāo)名

     舉例:delete from authors where current of authors_crsr

     當(dāng)游標(biāo)刪除一行后,SQL Server將游標(biāo)置于被刪除行的前一行上。

     更新游標(biāo)當(dāng)前行的語(yǔ)法為:

       update 表名

       set column_name1={expression1|NULL|(select_statement)}

              [,column_name2={expression2|NULL|(select_statement)}

              [……]

       where current of 游標(biāo)名

      舉例:

        update company

        set name=”張三”,salary=”5000”

        where current of company_crsr

    (4)關(guān)閉游標(biāo)

       當(dāng)結(jié)束一個(gè)游標(biāo)結(jié)果集時(shí),可用close關(guān)閉。該語(yǔ)法為:

           close 游標(biāo)名

       關(guān)閉游標(biāo)并不改變其定義,可用open再次打開(kāi)。若想放棄游標(biāo),必須使用deallocate釋放它,deallocater的語(yǔ)法為:

        deallocater cursor 游標(biāo)名

        deallocater語(yǔ)句通知SQL Server釋放Declare語(yǔ)句使用的共享內(nèi)存,不再允許另一進(jìn)程在其上執(zhí)行Open操作。