游標為您提供了在逐行的基礎上而不是一次處理整個結果集為基礎的操作表中數據的方法。
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確定游標中的行數;
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
MSSQL 游標使用 心得
2019-11-06 13:09mssql教程網 Sql Server
MS-SQL游標的使用及理解 windows或DOS的“光標”不同,MS-SQL的游標是一種臨時的數據庫對象,既對可用來旋轉儲存在系統永久表中的數據行的副本,也可以指向儲存在系統永久表中的數據行的指針。
延伸 · 閱讀
- 2022-03-09SQL利用游標遍歷日期查詢的過程詳解
- 2022-03-05MSSQL 附加數據庫提示“錯誤 823”數據恢復實操
- 2022-02-10MySQL游標詳細介紹
- 2022-01-11易語言調用MS SQL SERVER數據庫方法
- 2021-12-26護衛神主機管理系統使用說明之主機MSSQL管理
- 2021-12-15SQL中游標(cursor)的基本使用實例
- Sql Server
SQL2005 存儲過程解密方法
SQL2005 存儲過程解密方法,需要的朋友可以參考下。...
- Sql Server
三種SQL分頁查詢的存儲過程代碼
三種SQL分頁查詢的存儲過程代碼,需要的朋友可以參考下。 ...
- Sql Server
SQLServer2005創建定時作業任務
這篇文章主要為大家介紹了SQLServer2005創建定時作業任務的詳細過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下 ...
- Sql Server
深入SQLServer中ISNULL與NULLIF的使用詳解
本篇文章是對SQLServer中ISNULL與NULLIF的使用進行了詳細分析介紹,需要的朋友參考下 ...
- Sql Server
SQL JOIN 連接詳細介紹及簡單使用實例
這篇文章主要介紹了SQL JOIN 連接詳細介紹及簡單使用實例的相關資料,需要的朋友可以參考下 ...
- Sql Server
SQLServer2005 批量查詢自定義對象腳本
SQLServer2005 批量查詢自定義對象腳本,使用系統函數object_definition和系統表 sysobjects 就可以了 ...
- Sql Server
SQL_Server全文索引的用法解析
SQL Server全文索引相信大家都有一定的了解,下面就為您介紹SQL Server全文索引的用法及相關的語句,希望可以讓您對SQL Server全文索引能有更深的認識 ...
- Sql Server
SQLServer 數據庫的數據匯總完全解析(WITH ROLLUP)
乍一看,好像很容易,用group by好像能實現?但仔細研究下去,你又會覺得group by也是無能為力,總欠缺點什么,無從下手。那么,到底該如何做呢?別急,...