遊標是SQL數據庫中不可或缺的部分,能夠旋轉儲存在系統永久表中的數據行的副本,下面就將爲您詳解遊標的使用,以及語法,供您參考學習。web
MS-SQL的遊標是一種臨時的數據庫對象,既對可用來旋轉儲存在系統永久表中的數據行的副本,也能夠指向儲存在系統永久表中的數據行的指針。
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
簡單的過程:
定義遊標
DECLARE CustomerCursor CURSOR FOR
SELECT acct_no,name,balance
FROM customer
WHERE province="北京";
打開遊標
OPEN CustomerCursor;
提取數據--設置循環
lb_continue=True緩存
ll_total=0
DO WHILE lb_continue
FETCH CustomerCursor
INTO:ls_acct_no, :ls_name, :ll_balance;
If sqlca.sqlcode=0 Then
ll_total+=ll_balance
Else
lb_continue=False
End If
LOOP
關閉遊標
CLOSE CustomerCursor;
服務器
2.語句的詳細及注意ide
1) 定義遊標語句
Declare <遊標名> [Insensitive] [Scroll] Cursor
For [FOR {Read Only | Update [ OF <列名列表>]}] u Insensitive DBMS建立查詢結果集數據的臨時副本(而不是使用直接引用數據庫表中的真實數據行中的列)。遊標是Read Only,也就是說不能修改其內容或底層表的內容; u Scroll 指定遊標支持經過使用任意Fetch 選項(First Last Prior Next Relative Absolute)選取它的任意行做爲當前行。若是此項省略,則遊標將只支持向下移動單行(即只支持遊標的Fetch Next); u Select語句 定義遊標結果集的標準 SELECT 語句。在遊標聲明的 內不容許使用關鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO; u Read Only 防止使用遊標的用戶經過更新數據或刪除行改變遊標的內容; u 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; u Next 向下、向後移動一行(記錄); u Prior 向上、向前移動一行(記錄); u First 移動至結果集的第一行(記錄); u Last 移動至結果集的最後一行(記錄); u Absolute n 移動到結果集中的第n行。若是n是正值,DBMS從結果集的首部向後或向下移動至第n行;若是n是負數,則DBMS從結果集的底部向前或向上移動n行; Fetch Absolute 2 From cur_Depart Into @DeptID,@DeptName u 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肯定遊標中的行數 fetch
4.使用系統過程管理遊標
在創建一個遊標以後,即可利用系統過程對遊標進行管理管理,遊標的系統過程主要有如下幾個:sp_cursor_list、sp_describe_cursor、 sp_describe_cursor_tables 、sp_describe_cursor_columns。
1) sp_cursor_list 顯示在當前做用域內的遊標及其屬性。其命令格式爲:
">sp_cursor_list [ @cursor_return = ] cursor_variable_name OUTPUT,
[ @cursor_scope = ] cursor_scope
參數:
· [@cursor_return =] cursor_variable_name OUTPUT:聲明的遊標變量的名稱。cursor_variable_name 的數據類型爲 cursor,沒有默認值。遊標是可滾動的、動態的只讀遊標。
· [@cursor_scope =] cursor_scope:指定要報告的遊標級別。cursor_scope 的數據類型爲 int,沒有默認值,能夠是下列值中的一個。spa
值描述
1 報告全部本地遊標。
2 報告全部全局遊標。
3 報告本地遊標和全局遊標。
提示:因爲sp_cursor_list是一個含有遊標類型變量@cursor_return,且有OUTPUT保留字的系統過程,遊標變量@cursor_return中的結果集與pub_cur遊標中的結果集是不一樣的。
2) sp_describe_cursor 報告服務器遊標的特性。
sp_describe_cursor [ @cursor_return = ] output_cursor_variable OUTPUT
{ [ , [ @cursor_source = ] N''local''
, [ @cursor_identity = ] N''local_cursor_name'' ]
| [ , [ @cursor_source = ] N''global''
, [ @cursor_identity = ] N''global_cursor_name'' ]
| [ , [ @cursor_source = ] N''variable''
, [ @cursor_identity = ] N''input_cursor_variable'' ]
}
參數:
· [@cursor_return =] output_cursor_variable OUTPUT:聲明遊標變量的名稱,該變量接收遊標輸出。output_cursor_variable 的數據類型爲 cursor,沒有默認值。調用 sp_describe_cursor 時,不能與任何遊標相關聯。返回的遊標是可滾動的動態只讀遊標。
· [@cursor_source =] { N''local'' | N''global'' | N''variable'' }:指定是使用本地遊標的名稱、全局遊標的名稱、仍是遊標變量的名稱來指定當前正在對其進行報告的遊標。參數是 nvarchar(30)。
· [@cursor_identity =] N''local_cursor_name'']:由具備 LOCAL 關鍵字或默認設置爲 LOCAL 的 DECLARE CURSOR 語句建立的遊標的名稱。local_cursor_name 的數據類型爲 nvarchar(128)。
· [@cursor_identity =] N''global_cursor_name'']:由具備 GLOBAL 關鍵字或默認設置爲 GLOBAL 的 DECLARE CURSOR 語句建立的遊標的名稱。也能夠是由 ODBC 應用程序打開而後經過調用 SQLSetCursorName 對遊標命名的 API 服務器遊標的名稱。global_cursor_name 的數據類型爲 nvarchar(128)。
· [@cursor_identity =] N''input_cursor_variable'']:與開放遊標相關聯的遊標變量的名稱。input_cursor_variable 的數據類型爲 nvarchar(128)。
提示: sp_descride_cursor_tables和sp_describe_cursor_columms的命令格式與sp_describe_cursor的命令格式同樣。
5.遊標種類
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 count(id) from info
select * from info
--清除全部記錄
truncate table info
declare @i int
set @i=1
while @i<1000000
begin
insert into info values(''Justin''+str(@i),''深圳''+str(@i))
set @i=@i+1
end
6.遊標和遊標的優勢
在數據庫中,遊標是一個十分重要的概念。遊標提供了一種對從表中檢索出的數據進行操做的靈活手段,就本質而言,遊標其實是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。遊標老是與一條T_SQL 選擇語句相關聯由於遊標由結果集(能夠是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的遊標位置組成。當決定對結果集進行處理時,必須聲明一個指向該結果集的遊標。若是曾經用 C 語言寫過對文件進行處理的程序,那麼遊標就像您打開文件所獲得的文件句柄同樣,只要文件打開成功,該文件句柄就可表明該文件。對於遊標而言,其道理是相同的。可見遊標可以實現按與傳統程序讀取平面文件相似的方式處理來自基礎表的結果集,從而把表中數據以平面文件的形式呈現給程序。
咱們知道關係數據庫管理系統實質是面向集合的,在MS SQL中並無一種描述表中單一記錄的表達形式,除非使用where 子句來限制只有一條記錄被選中。所以咱們必須藉助於遊標來進行面向單條記錄的數據處理。 SERVER
因而可知,遊標容許應用程序對查詢語句select 返回的行結果集中每一行進行相同或不一樣的操做,而不是一次對整個結果集進行同一種操做;它還提供對基於遊標位置而對錶中數據進行刪除或更新的能力;並且,正是遊標把做爲面向集合的數據庫管理系統和麪向行的程序設計二者聯繫起來,使兩個數據處理方式可以進行溝通。
以[master].[dbo].[spt_values] 這個表爲例子
===
declare @name nvarchar(35)
declare @number int
declare my_cursor cursor for --定義遊標cursor1
select TOP 5 [name],[number] from [spt_values] --使用遊標的對象(跟據須要填入select文)
open my_cursor --打開遊標
fetch next from my_cursor into @name,@number --將遊標向下移1行,獲取的數據放入以前定義的變量@id,@name中
while(@@fetch_status=0) --判斷是否成功獲取數據
begin
--update [spt_values] set [name]=@name+'1'
--where [number]=@number+1 --進行相應處理(跟據須要填入SQL文)
print @name
print @number
print '===='
fetch next from my_cursor into @name,@number --將遊標向下移1行
end
close my_cursor --關閉遊標
deallocate my_cursor
=====================如下是基礎
blog.csdn.net/lejuo/archive/2008/11/12/3279340.aspx
可百度 SQL遊標語法及舉例 進行更深刻學習
遊標的定義:
每個遊標必須有四個組成部分這四個關鍵部分必須符合下面的順序;
1.DECLARE 遊標
2.OPEN 遊標
3.從一個遊標中FETCH 信息
4.CLOSE 或DEALLOCATE 遊標
一般咱們使用DECLARE 來聲明一個遊標聲明一個遊標主要包括如下主要內容:
遊標名字
數據來源(表和列)
選取條件
屬性(僅讀或可修改)
其語法格式以下:
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
其中:
cursor_name
指遊標的名字。
INSENSITIVE
代表MS SQL SERVER 會將遊標定義所選取出來的數據記錄存放在一臨時表內(創建在tempdb 數據庫下)。對該遊標的讀取操做皆由臨時表來應答。所以,對基本表的修改並不影響遊標提取的數據,即遊標不會隨着基本表內容的改變而改變,同時也沒法經過
遊標來更新基本表。若是不使用該保留字,那麼對基本表的更新、刪除都會反映到遊標中。
另外應該指出,當遇到如下狀況發生時,遊標將自動設定INSENSITIVE 選項。在SELECT 語句中使用DISTINCT、 GROUP BY、 HAVING UNION 語句;使用OUTER JOIN;所選取的任意表沒有索引;將實數值看成選取的列。SCROLL表 明全部的提取操做(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)均可用。若是不使用該保留字,那麼只能進行NEXT 提取操做。因而可知,SCROLL 極大地增長了提取數據的靈活性,能夠隨意讀取結果集中的任一行數據記錄,而沒必要關閉再重開遊標。select_statement是定義結果集的SELECT 語句。應該注意的是,在遊標中不能使用COMPUTE、COMPU- TE BY、 FOR BROWSE、 INTO 語句。READ ONLY代表不容許遊標內的數據被更新儘管在缺省狀態下游標是容許更新的。並且在UPDATE或DELETE 語句的WHERE CURRENT OF 子句中,不容許對該遊標進行引用。UPDATE [OF column_name[,…n]]定義在遊標中可被修改的列,若是不指出要更新的列,那麼全部的列都將被更新。當遊標被成功創。