1. 程式人生 > >MS-SQL遊標的使用及理解

MS-SQL遊標的使用及理解

與windows或DOS的“游標”不同,MS-SQL的遊標是一種臨時的資料庫物件,既對可用來旋轉儲存在系統永久表中的資料行的副本,也可以指向儲存在系統永久表中的資料行的指標。
遊標為您提供了在逐行的基礎上而不是一次處理整個結果集為基礎的操作表中資料的方法。

1.如何使用遊標

1)定義遊標語句 Declare <遊標名> Cursor For
2)建立遊標語句 Open <遊標名>
3)提取遊標列值、移動記錄指標 Fetch <列名列表> From <遊標名> [Into <變數列表>]
4)使用@@Fetch_Status利用While迴圈處理遊標中的行
5)刪除遊標並釋放語句 Close <遊標名>/Deallocate <遊標名>
6)遊標應用例項

--定義遊標
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
--建立遊標
Open cur_Depart
--移動或提取列值
Fetch From cur_Depart into @DeptID,@DeptName
--利用迴圈處理遊標中的列值
While @@Fetch_Status=0
Begin
Print @DeptID,@DeptName
Fetch From cur_Depart into @DeptID,@DeptName
End
--關閉/釋放遊標
Close cur_Depart
Deallocate cur_Depart

2.語句的詳細及注意

1)定義遊標語句

Declare <遊標名> [Insensitive] [Scroll] Cursor
For <Select 語句> [FOR {Read Only | Update [ OF <列名列表>]}]

  • Insensitive DBMS建立查詢結果集資料的臨時副本(而不是使用直接引用資料庫表中的真實資料行中的列)。遊標是Read Only,也就是說不能修改其內容或底層表的內容;
  • Scroll 指定遊標支援通過使用任意Fetch 選項(First Last Prior Next Relative Absolute)選取它的任意行作為當前行。如果此項省略,則遊標將只支援向下移動單行(即只支援遊標的Fetch Next);
  • Select語句 定義遊標結果集的標準 SELECT 語句。在遊標宣告的 <Select語句>內不允許使用關鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO;
  • Read Only 防止使用遊標的使用者通過更新資料或刪除行改變遊標的內容;
  • Update 建立可更新遊標且列出值能被更新的遊標列。如果子句中列入了任意列,則只有被列入的列才能被更新。如果Declare Cursor語句中只指定的UPDATE(沒有列名列表),則遊標將允許更新它的任何或所有列。
    Declare cur_Depart Cursor
    For Select * From Department For Update OF cDeptID,cDeptName

2)提取遊標列值、移動記錄指標語句

Fetch [Next | Prior | First | Last | {Absolute <行號>} | {Relative <行號>}]
From <遊標名> [Into <變數列表……>]

  • 每次執行Fetch語句時,DBMS移到遊標中的下一行並把遊標中的列值獲取到Into中列出的變數中。因此Fetch語句的Into子句中列出的變數必須與遊標定義中Select 語句中的列表的型別與個數相對應;
  • 僅當定義遊標時使用Scroll引數時,才能使用Fetch語句的行定位引數(First Last Prior Next Relative Absolute);如果Fetch語句中不包括引數Next | Prior | First | Last,DBMS將執行預設的Fetch Next;
  • Next 向下、向後移動一行(記錄);
  • Prior 向上、向前移動一行(記錄);
  • First 移動至結果集的第一行(記錄);
  • Last 移動至結果集的最後一行(記錄);
  • Absolute n 移動到結果集中的第n行。如果n是正值,DBMS從結果集的首部向後或向下移動至第n行;如果n是負數,則DBMS從結果集的底部向前或向上移動n行;
    Fetch Absolute 2 From cur_Depart Into @DeptID,@DeptName
  • Relative n 從指標的當前位置移動n行。如果n是正值,DBMS將行指標向後或向下移動至第n行;如果n是負數,則DBMS將行指標向前或向上移動n行;
    Fetch Relative 2 From cur_Depart Into @DeptID,@DeptName

3)基於遊標的定位DELETE/UPDATE語句

如果遊標是可更新的(也就是說,在定義遊標語句中不包括Read Only 引數),就可以用遊標從遊標資料的源表中DELETE/UPDATE行,即DELETE/UPDATE基於遊標指標的當前位置的操作;
舉例:

--刪除當前行的記錄
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
Open cur_Depart
Fetch From cur_Depart into @DeptID,@DeptName
Delete From Department Where CURRENT OF cur_Depart

--更新當前行的內容
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
Open cur_Depart
Fetch From cur_Depart into @DeptID,@DeptName
Update Department Set cDeptID=’2007’ + @DeptID Where CURRENT OF cur_Depart

3.遊標使用技巧及注意

1)利用Order By改變遊標中行的順序。此處應該注意的是,只有在查詢的中Select 子句中出現的列才能作為Order by子句列,這一點與普通的Select語句不同;
2)當語句中使用了Order By子句後,將不能用遊標來執行定位DELETE/UPDATE語句;如何解決這個問題,首先在原表上建立索引,在建立遊標時指定使用此索引來實現;例如:

Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department With INDEX(idx_ID)
For Update Of cDeptID,cDeptName

通過在From子句中增加With Index來實現利用索引對錶的排序;


3)在遊標中可以包含計算好的值作為列;
4)利用@@Cursor_Rows確定遊標中的行數;