SQLServer遊標(Cursor) (B)

遊標(Cursor)是處理數據的一種方法,爲了查看或者處理結果集中的數據,遊標提供了在結果集中一次以行或者多行前進或向後瀏覽數據的能力。咱們能夠把遊標看成一個指針,它能夠指定結果中的任何位置,而後容許用戶對指定位置的數據進行處理。數據庫

      1.遊標的組成緩存

      遊標包含兩個部分:一個是遊標結果集、一個是遊標位置。服務器

      遊標結果集:定義該遊標得SELECT語句返回的行的集合。遊標位置:指向這個結果集某一行的當前指針。函數

 

      2.遊標的分類spa

      遊標共有3類:API服務器遊標、Transaction-SQL遊標和API客戶端遊標。指針

      其中前兩種遊標都是運行在服務器上的,因此又叫作服務器遊標。生命週期

      API服務器遊標作用域

      API服務器遊標主要應用在服務上,當客戶端的應用程序調用API遊標函數時,服務器會對API函數進行處理。使用API函數和方法能夠實現以下功能:io

      (1)打開一個鏈接。ast

      (2)設置定義遊標特徵的特性或屬性,API自動將遊標影射到每一個結果集。

      (3)執行一個或多個Transaction-SQL語句。

      (4)使用API函數或方法提取結果集中的行。

      API服務器遊標包含如下四種:靜態遊標、動態遊標、只進遊標、鍵集驅動遊標(Primary key)

      靜態遊標的完整結果集將打開遊標時創建的結果集存儲在臨時 表中,(靜態遊標始終是隻讀的)。靜態遊標具備如下特色:老是按照打開遊標時的原樣顯示結果集;不反映數據庫中做的任何修改,也不反映對結果集行的列值所 做的更改;不顯示打開遊標後在數據庫中新插入的行;組成結果集的行被其餘用戶更新,新的數據值不會顯示在靜態遊標中;可是靜態遊標會顯示打開遊標之後從數 據庫中刪除的行。

      動態遊標與靜態遊標相反,當滾動遊標時動態遊標反映結果集中的全部更改。結果集中的行數據值、順序和成員每次提取時都會改變。

      只進遊標不支持滾動,它只支持遊標從頭至尾順序提取數據行。注意:只進遊標也反映對結果集所作的全部更改。

      鍵集驅動遊標同時具備靜態遊標和動態遊標的特色。當打開遊標時,該遊標中的成員以及行的順序是固定的,鍵集在遊標打開時也會存儲到臨時工做表中,對非鍵集列的數據值的更改在用戶遊標滾動的時候能夠看見,在遊標打開之後對數據庫中插入的行是不可見的,除非關閉從新打開遊標。

 

      Transaction-SQL遊標

      該遊標是基於Declare Cursor 語法,主要用於Transaction-SQL腳本、存儲過程以及觸發器中。Transaction-SQL遊標在服務器處理由客戶端發送到服務器的Transaction-SQL語句。

      在存儲過程或觸發器中使用Transaction-SQL遊標的過程爲:

      (1)聲明Transaction-SQL變量包含遊標返回的數據。爲每一個結果集列聲明一個變量。聲明足夠大的變量來保存列返回的值,並聲明變量的類型爲可從數據類型隱式轉換獲得的數據類型。

      (2)使用Declare Cursor語句將Transaction-SQL遊標與Select語句相關聯。還能夠利用Declare Cursor定義遊標的只讀、只進等特性。 

      (3)使用Open語句執行Select語句填充遊標。

      (4)使用Fetch Into語句提取單個行,並將每列中得數據移至指定的變量中。注意:其餘Transaction-SQL語句能夠引用那些變量來訪問提取的數據值。Transaction-SQL遊標不支持提取行塊。

      (5)使用Close語句結束遊標的使用。注意:關閉遊標之後,該遊標仍是存在,可使用Open命令打開繼續使用,只有調用Deallocate語句纔會徹底釋放。

      客戶端遊標

      該遊標將使用默認結果集把整個結果集高速緩存在客戶端上,全部的遊標操做都在客戶端的高速緩存中進行。注意:客戶端遊標只支持只進和靜態遊標。不支持其餘遊標。

 

      3.遊標的生命週期

      遊標的生命週期包含有五個階段:聲明遊標、打開遊標、讀取遊標數據、關閉遊標、釋放遊標。

      聲明遊標是爲遊標指定獲取數據時所使用的Select語句,聲明遊標並不會檢索任何數據,它只是爲遊標指明瞭相應的Select 語句。

      Declare 遊標名稱 Cursor 參數

      聲明遊標的參數

            (1)Local與Global:Local表示遊標的做用於僅僅限於其所在的存儲過程、觸發器以及批處理中、執行完畢以 後遊標自動釋放。Global表示的是該遊標做用域是整個會話層。由鏈接執行的任何存儲過程、批處理等均可以引用該遊標名稱,僅在斷開鏈接時隱性釋放。

            (2)Forward_only與Scroll:前者表示爲只進遊標,後者表示爲能夠隨意定位。默認爲前者。

            (3)Static、Keyset與Dynamic: 第一個表示定義一個遊標,其數據存放到一個臨時表內,對遊標的全部請求都從臨時表中應答,所以,對該遊標進行提取操做時返回的數據不反映對基表所做的修 改,而且該遊標不容許修改。Keyset表示的是,當遊標打開時,鍵集驅動遊標中行的身份與順序是固定的,並把其放到臨時表中。Dynamic表示的是滾 動遊標時,動態遊標反映對結果集內全部數據的更改。

            (4)Read_only 、Scroll_Locks與Optimistic:第一個表示的是隻讀遊標,第二個表示的是 在使用的遊標結果集數據上放置鎖,當行讀取到遊標中而後對它們進行修改時,數據庫將鎖定這些行,以保證數據的一致性。Optimistic的含義是遊標將 數據讀取之後,若是這些數據被更新了,則經過遊標定位進行的更新與刪除操做將不會成功。

      標準遊標:

            Declare MyCursor Cursor 
                   For Select * From Master_Goods

      只讀遊標

            Declare MyCusror Cursor

                  For Select * From Master_Goods

                  For Read Only

      可更新遊標

            Declare MyCusror Cursor

                  For Select * From Master_Goods

                  For UpDate

      打開遊標使用Open語句用於打開Transaction-SQL服務器遊標,執行Open語句的過程當中就是按照Select語句進行填充數據,打開遊標之後遊標位置在第一行。

      打開遊標

            全局遊標:Open Global MyCursor            局部遊標: Open MyCursor

      讀取遊標數據:在打開遊標之後,使用Fetch語句從Transaction-SQL服務器遊標中檢索特定的一行。使用Fetch操做,可使遊標移動到下一個記錄,並將遊標返回的每一個列得數據分別賦值給聲明的本地變量。

            Fetch [Next | Prior | First | Last | Absolute n | Relative n ]  From MyCursor

            Into @GoodsID,@GoodsName

            其中:Next表示返回結果集中當前行的下一行記錄,若是第一次讀取則返回第一行。默認的讀取選項爲Next

                   Prior表示返回結果集中當前行的前一行記錄,若是第一次讀取則沒有行返回,而且把遊標置於第一行以前。

                   First表示返回結果集中的第一行,而且將其做爲當前行。

                   Last表示返回結果集中的最後一行,而且將其做爲當前行。

                   Absolute n 若是n爲正數,則返回從遊標頭開始的第n行,而且返回行變成新的當前行。若是n爲負,則返回從遊標末尾開始的第n行,而且返回行爲新的當前行,若是n爲0,則返回當前行。

                   Relative n 若是n爲正數,則返回從當前行開始的第n行,若是n爲負,則返回從當前行以前的第n行,若是爲0,則返回當前行。

      關閉遊標調用的是Close語句,方式以下:Close Global MyCursor               Close MyCursor

      釋放遊標調用的是Deallocate語句,方法以下:Deallocate Glboal MyCursor       Deallocate MyCursor

 

      遊標實例:

            Declare MyCusror Cursor Scroll

                  For Select * From Master_Goods Order By GoodsID

            Open MyCursor

            Fetch next From MyCursor
            Into @GoodsCode,@GoodsName

            While(@@Fetch_Status = 0)
                  Begin

                         Begin
                               Select @GoodsCode = Convert(Char(20),@GoodsCode)
                               Select @GoodsName = Convert(Char(20),@GoodsName)
                               PRINT @GoodsCode + ':' + @GoodsName
                         End

                         Fetch next From MyCursor
                         Into @GoodsCode,@GoodsName

                  End
            Close MyCursor
            Deallocate MyCursor

 

      修改當前遊標的數據方法以下:

            UpDate Master_Goods Set GoodsName = 'yangyang8848' Where Current Of MyCursor;
      刪除當前遊標行數據的方法以下: 
            Delete From Master_Goods Where Current Of MyCursor

 

      Select @@CURSOR_ROWS 能夠獲得當前遊標中存在的數據行數。注意:此變量爲一個鏈接上的全局變量,所以只對應最後一次打開的遊標。

相關文章
相關標籤/搜索