游標為您提供了在逐行的基礎上而不是一次處理整個結果集為基礎的操作表中數(shù)據的方法。 1.如何使用游標 1)定義游標語句 Declare 游標名> Cursor For 2)創(chuàng)建游標語句 Open 游標名> 3)提取游標列值、移動記錄指針 Fetch 列名列表> From 游標名> [Into 變量列表>] 4)使用@@Fetch_Status利用While循環(huán)處理游標中的行 5)刪除游標并釋放語句 Close 游標名>/Deallocate 游標名> 6)游標應用實例 --定義游標 Declare cur_Depart Cursor For Select cDeptID,cDeptName From Department into @DeptID,@DeptName --創(chuàng)建游標 Open cur_Depart --移動或提取列值 Fetch From cur_Depart into @DeptID,@DeptName --利用循環(huán)處理游標中的列值 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創(chuàng)建查詢結果集數(shù)據的臨時副本(而不是使用直接引用數(shù)據庫表中的真實數(shù)據行中的列)。游標是Read Only,也就是說不能修改其內容或底層表的內容; Scroll 指定游標支持通過使用任意Fetch 選項(First Last Prior Next Relative Absolute)選取它的任意行作為當前行。如果此項省略,則游標將只支持向下移動單行(即只支持游標的Fetch Next); Select語句 定義游標結果集的標準 SELECT 語句。在游標聲明的 Select語句>內不允許使用關鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO; Read Only 防止使用游標的用戶通過更新數(shù)據或刪除行改變游標的內容; Update 創(chuàng)建可更新游標且列出值能被更新的游標列。如果子句中列入了任意列,則只有被列入的列才能被更新。如果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 變量列表……>] 每次執(zhí)行Fetch語句時,DBMS移到游標中的下一行并把游標中的列值獲取到Into中列出的變量中。因此Fetch語句的Into子句中列出的變量必須與游標定義中Select 語句中的列表的類型與個數(shù)相對應; 僅當定義游標時使用Scroll參數(shù)時,才能使用Fetch語句的行定位參數(shù)(First Last Prior Next Relative Absolute);如果Fetch語句中不包括參數(shù)Next | Prior | First | Last,DBMS將執(zhí)行默認的Fetch Next; Next 向下、向后移動一行(記錄); Prior 向上、向前移動一行(記錄); First 移動至結果集的第一行(記錄); Last 移動至結果集的最后一行(記錄); Absolute n 移動到結果集中的第n行。如果n是正值,DBMS從結果集的首部向后或向下移動至第n行;如果n是負數(shù),則DBMS從結果集的底部向前或向上移動n行; Fetch Absolute 2 From cur_Depart Into @DeptID,@DeptName Relative n 從指針的當前位置移動n行。如果n是正值,DBMS將行指針向后或向下移動至第n行;如果n是負數(shù),則DBMS將行指針向前或向上移動n行; Fetch Relative 2 From cur_Depart Into @DeptID,@DeptName 3)基于游標的定位DELETE/UPDATE語句 如果游標是可更新的(也就是說,在定義游標語句中不包括Read Only 參數(shù)),就可以用游標從游標數(shù)據的源表中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 子句中出現(xiàn)的列才能作為Order by子句列,這一點與普通的Select語句不同; 2)當語句中使用了Order By子句后,將不能用游標來執(zhí)行定位DELETE/UPDATE語句;如何解決這個問題,首先在原表上創(chuàng)建索引,在創(chuàng)建游標時指定使用此索引來實現(xiàn);例如: Declare cur_Depart Cursor For Select cDeptID,cDeptName From Department With INDEX(idx_ID) For Update Of cDeptID,cDeptName 通過在From子句中增加With Index來實現(xiàn)利用索引對表的排序; 3)在游標中可以包含計算好的值作為列; 4)利用@@Cursor_Rows確定游標中的行數(shù); ALTER FUNCTION SEL_KEYAR(@YEARNUM INT,@f_k_lessonid VARCHAR(15)) RETURNS VARCHAR(8000) AS BEGIN DECLARE @NIAN VARCHAR(8000),@NUMS INT,@NIANS VARCHAR(8000) SET @NUMS=1 DECLARE GETYEAR CURSOR FOR SELECT f_year FROM t_kejianol WHERE f_k_lessonid=@f_k_lessonid GROUP BY f_year ORDER BY f_year DESC OPEN GETYEAR FETCH NEXT FROM GETYEAR INTO @NIAN WHILE @@FETCH_STATUS=0 BEGIN IF @YEARNUM=@NUMS SET @NIANS=ISNULL(@NIANS+',','')+RTRIM(@NIAN) SELECT @NUMS=@NUMS+1 FETCH NEXT FROM GETYEAR INTO @NIAN --FETCH ABSOLUTE 3 FROM GETYEAR INTO @NIAN END CLOSE GETYEAR DEALLOCATE GETYEAR --PRINT @NIANS RETURN @NIANS END ALTER FUNCTION SEL_KEYAR(@YEARNUM INT,@f_k_lessonid VARCHAR(15)) RETURNS VARCHAR(8000) AS BEGIN DECLARE @NIAN VARCHAR(8000),@NIANS VARCHAR(8000) DECLARE GETYEAR CURSOR FOR SELECT f_year FROM t_kejianol WHERE f_k_lessonid=@f_k_lessonid GROUP BY f_year ORDER BY f_year ASC OPEN GETYEAR FETCH ABSOLUTE @YEARNUM FROM GETYEAR INTO @NIAN CLOSE GETYEAR DEALLOCATE GETYEAR RETURN @NIANS END