遊標

遊標是系統爲用戶開設的一個數據緩衝區,存放SQL語句的執行結果。每個遊標區都有一個名字。用戶可以用SQL語句逐一從遊標中獲取記錄,並賦給主變量,交由主語言進一步處理。主語言是面向記錄的,一組主變量一次只能存放一條記錄。僅使用主變量並不能完全滿足SQL語句嚮應用程序輸出數據的要求。嵌入式SQL引入了遊標的概念,用來協調這兩種不同的處理方式。在數據庫開發過程中,當你檢索的數據只是一條記錄時,你所編寫的事務語句代碼往往使用SELECT INSERT 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?遊標爲我們提供了一種極爲優秀的解決方案。
  


  在數據庫中,遊標是一個十分重要的概念。遊標提供了一種對從表中檢索出的數據進行操作的靈活手段,就本質而言,遊標實際上是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。遊標總是與一條SQL 選擇語句相關聯因爲遊標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的遊標位置組成。當決定對結果集進行處理時,必須聲明一個指向該結果集的遊標。如果曾經用 C 語言寫過對文件進行處理的程序,那麼遊標就像您打開文件所得到的文件句柄一樣,只要文件打開成功,該文件句柄就可代表該文件。對於遊標而言,其道理是相同的。可見遊標能夠實現按與傳統程序讀取平面文件類似的方式處理來自基礎表的結果集,從而把表中數據以平面文件的形式呈現給程序。
  我們知道關係數據庫管理系統實質是面向集合的,在MS SQL SERVER 中並沒有一種描述表中單一記錄的表達形式,除非使用where 子句來限制只有一條記錄被選中。因此我們必須藉助於遊標來進行面向單條記錄的數據處理。由此可見,遊標允許應用程序對查詢語句select 返回的行結果集中每一行進行相同或不同的操作,而不是一次對整個結果集進行同一種操作;它還提供對基於遊標位置而對錶中數據進行刪除或更新的能力;而且,正是遊標把作爲面向集合的數據庫管理系統和麪向行的程序設計兩者聯繫起來,使兩個數據處理方式能夠進行溝通。
  


  MS SQL SERVER 支持三種類型的遊標:Transact_SQL 遊標,API 服務器遊標和客戶遊標。
  (1) Transact_SQL 遊標
  Transact_SQL 遊標是由DECLARE CURSOR 語法定義、主要用在Transact_SQL 腳本、存儲過程和觸發器中。Transact_SQL 遊標主要用在服務器上,由從客戶端發送給服務器的Transact_SQL 語句或是批處理、存儲過程、觸發器中的Transact_SQL 進行管理。 Transact_SQL 遊標不支持提取數據塊或多行數據。
  (2) API遊標
  API 遊標支持在OLE DB, ODBC 以及DB_library 中使用遊標函數,主要用在服務器上。每一次客戶端應用程序調用API 遊標函數,MS SQL SEVER 的OLE DB 提供者、ODBC驅動器或DB_library 的動態鏈接庫(DLL) 都會將這些客戶請求傳送給服務器以對API遊標進行處理。
  (3) 客戶遊標
  客戶遊標主要是當在客戶機上緩存結果集時才使用。在客戶遊標中,有一個缺省的結果集被用來在客戶機上緩存整個結果集。客戶遊標僅支持靜態遊標而非動態遊標。由於服務器遊標並不支持所有的Transact-SQL 語句或批處理,所以客戶遊標常常僅被用作服務器遊標的輔助。因爲在一般情況下,服務器遊標能支持絕大多數的遊標操作。由於API 遊標和Transact-SQL 遊標使用在服務器端,所以被稱爲服務器遊標,也被稱爲後臺遊標,而客戶端遊標被稱爲前臺遊標。
遊標包含兩方面的內容:
   ●遊標結果集:執行其中的Select語句所得到的結果集;
   ●遊標位置:一個指向遊標結果集內的某一條記錄的指針
   利用遊標可以單獨操縱結果集中的每一行。遊標在定義以後存在兩種狀態:關閉和打開。
當遊標關閉時,其查詢結果集不存在;只有當遊標打開時,才能按行讀取或修改結果集中的數據。
   使用遊標
   無論使用哪一種遊標,都需要經過如下幾個步驟:
   ●定義遊標
   ●打開遊標
   ●從遊標中操作數據
   ●關閉遊標 
 
下面是用法
DECLARE cursor1 cursor     /* 聲明遊標,默認爲FORWARD_ONLY遊標 */
FOR SELECT * FROM books
OPEN cursor1                /* 打開遊標 */
FETCH NEXT from cursor1     /* 讀取第1行數據*/
WHILE @@FETCH_STATUS = 0     /* 用WHILE循環控制遊標活動 */
BEGIN
          FETCH NEXT from cursor1   /* 在循環體內將讀取其餘行數據 */
END
CLOSE  cursor1               /* 關閉遊標 */
DEALLOCATE cursor 1    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章