SQL CURSOR 游標


/*
原理:游標就是把數據按照指定要求提取出相應的數據集,然后逐條進行數據處理。
1.1游標的概念
  游標(Cursor)它使用戶可逐行訪問由SQL Server返回的結果集。
 使用游標(cursor)的一個主要的原因就是把集合操作轉換成單個記錄處理方式。
 用SQL語言從數據庫中檢索數據后,結果放在內存的一塊區域中,且結果往往是一個含有多個記錄的集合。
 游標機制允許用戶在SQL server內逐行地訪問這些記錄,按照用戶自己的意願來顯示和處理這些記錄。
1.2 游標的優點
從游標定義可以得到游標的如下優點,這些優點使游標在實際應用中發揮了重要作用:
   1)允許程序對由查詢語句select返回的行集合中的每一行執行相同或不同的操作,而不是對整個行集合執行同一個操作。
   2)提供對基於游標位置的表中的行進行刪除和更新的能力。
   3)游標實際上作為面向集合的數據庫管理系統(RDBMS)和面向行的程序設計之間的橋梁,使這兩種處理方式通過游標溝通起來。

1.3 游標的使用
 講了這個多游標的優點,現在我們就親自來揭開游標的神秘的面紗。
 使用游標的順序: 聲名游標、打開游標、讀取數據、關閉游標、刪除游標。
1.3.1聲明游標
 最簡單游標聲明:DECLARE <游標名>CURSOR FOR<SELECT語句>;
 其中select語句可以是簡單查詢,也可以是復雜的接連查詢和嵌套查詢
1.3.2 打開游標
 非常簡單,我們就打開剛才我們聲明的游標mycursor
 OPEN mycursor
1.3.3讀取數據
  FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 游標名 | @游標變量名 } [ INTO @變量名 [,…] ]
  參數說明:
  NEXT   取下一行的數據,並把下一行作為當前行(遞增)。
 由於打開游標后,行指針是指向該游標第1行之前,所以第一次執行FETCH NEXT操作將取得游標集中的第1行數據。
 NEXT為默認的游標提取選項。
  INTO @變量名[,…] 把提取操作的列數據放到局部變量中。
 列表中的各個變量從左到右與游標結果集中的相應列相關聯。
 各變量的數據類型必須與相應的結果列的數據類型匹配或是結果列數據類型所支持的隱性轉換。
 變量的數目必須與游標選擇列表中的列的數目一致。  

1.3.4關閉游標
 CLOSE mycursor
1.3.5刪除游標
DEALLOCATE mycursor 

給出具體的例子:
*/

----------------------------------------------
declare @ID nvarchar(20); --定義變量來保存ID號
declare @DATE DATETIME; 
DECLARE @DFD NVARCHAR(200);          --定義變量來保存值
SET @DFD='';
declare mycursor cursor for
select MID,CreatedDate from FD_Menu   --為所獲得的數據集指定游標
open mycursor    --打開游標
fetch next from mycursor into @ID,@DATE   --開始抓第一條數據
while(@@fetch_status=0)     --如果數據集里一直有數據
begin
--select tb_b.name,(tb_b.gz + @A) from tb_b where tb_b.id = @id   --開始做想做的事(什么更新呀,刪除呀)
SET @DFD=@DFD+CAST(@ID AS NVARCHAR)+'.V.'+CONVERT(NVARCHAR,@DATE,111);
select @DFD;
        fetch next from mycursor into @ID,@DATE     --跳到下一條數據
end
close mycursor        --關閉游標
deallocate mycursor --刪除游標

-------------------------------------------------------------------------
-----------------------循環示例------------------------------------------
-------------------------------------------------------------------------
TRUNCATE TABLE V_TEST

DECLARE @i INT;
SET @i=1;
WHILE @i<1000
BEGIN
INSERT INTO V_TEST (V_Name,V_DESC)values('IamV'+str(@i),'Victor'+str(1000-@i))
SET @i=@i+1
END

SELECT * FROM V_TEST
-------------------------------------------------------------------------
DECLARE @ID BIGINT;
DECLARE @NAME NVARCHAR(50);
DECLARE V_CURSOR CURSOR FOR(
SELECT V_ID,V_Name FROM V_TEST WHERE RIGHT(V_NAME,2)='10'
)
OPEN V_CURSOR;
FETCH NEXT FROM V_CURSOR INTO @ID,@NAME
WHILE (@@FETCH_STATUS=0)
BEGIN
PRINT CAST(@ID AS NVARCHAR)+@NAME;
 FETCH NEXT FROM V_CURSOR INTO @ID,@NAME;
END
CLOSE V_CURSOR;
DEALLOCATE V_CURSOR;
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
/*
聲明 SCROLL 游標並使用其它 FETCH 選項
scroll表示可隨意移動游標指針(否則只能向前)
下例創建一個 SCROLL 游標,使其通過 LAST、PRIOR、RELATIVE 和 ABSOLUTE 選項支持所有滾動能力。
*/
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
--聲明局部變量
DECLARE @ID BIGINT;
DECLARE @NAME NVARCHAR(50);
DECLARE  V_CURSOR SCROLL CURSOR FOR
SELECT V_ID,V_Name FROM V_TEST;
OPEN V_CURSOR;
--定位到指定位置的記錄
FETCH ABSOLUTE 50 from V_CURSOR into @ID,@NAME
select @id as id,@name as name
--定位到當前記錄相對位置記錄
FETCH RELATIVE -30 from V_CURSOR into @id,@name
select @id as id,@name as name
--定位到當前記錄前一條
fetch prior from V_CURSOR into @id,@name
select @id as id,@name as name
--定位到當前記錄后一條
fetch next from V_CURSOR into @id,@name
select @id as id,@name as name
--定位到首記錄
fetch first from V_CURSOR into @id,@name
select @id as id,@name as name
--定位到尾記錄
fetch last from V_CURSOR into @id,@name
select @id as id,@name as name

CLOSE V_CURSOR;
DEALLOCATE V_CURSOR;
-------------------------------------------------------------------------------------
/*

*/
-------------------------------------------------------------------------------------
DECLARE @ID BIGINT;
DECLARE @NAME NVARCHAR(50);
DECLARE V_CURSOR CURSOR SCROLL FOR(
SELECT V_ID,V_Name FROM V_TEST WHERE RIGHT(V_NAME,2)='10'
)
OPEN V_CURSOR;
FETCH NEXT FROM V_CURSOR INTO @ID,@NAME

WHILE (@@FETCH_STATUS=0)
BEGIN
PRINT CAST(@ID AS NVARCHAR)+@NAME;
 FETCH RELATIVE 2 FROM V_CURSOR INTO @ID,@NAME;
END

CLOSE V_CURSOR;
DEALLOCATE V_CURSOR;
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
/*
dynamic表示可以讀寫游標(否則游標只讀)
UPDATE V_TEST SET V_DESC='Victor       199' WHERE CURRENT OF V_CURSOR
*/
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
DECLARE V_CURSOR CURSOR SCROLL DYNAMIC
/*scroll表示可隨意移動游標指針(否則只能向前)
dynamic表示可以讀寫游標(否則游標只讀)*/
FOR
SELECT V_DESC FROM V_TEST WHERE CAST(RIGHT(V_DESC,3) AS INT)<200

OPEN V_CURSOR
DECLARE @DESC NVARCHAR(50)

FETCH NEXT FROM V_CURSOR INTO @DESC
WHILE(@@fetch_status=0)
BEGIN
 PRINT 'Product Name: ' + @DESC
 FETCH NEXT FROM V_CURSOR INTO @DESC
END

FETCH FIRST FROM V_CURSOR INTO @DESC
print @DESC
update V_TEST set V_DESC='123122' WHERE CURRENT OF V_CURSOR
/**//*delete from product where current of my_cursor */
CLOSE V_CURSOR
DEALLOCATE V_CURSOR
----------------------------------------------------------------
SELECT * FROM V_TEST
update V_TEST set V_DESC='Victor       199' WHERE V_ID=801
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
/*
declare my_cursor1 cursor for
select nContentId,dtEditTime from content where datepart(month,dtEditTime)='9' and datepart(day,dtEditTime)='26'
open my_cursor1
declare @date sysname
declare @nID sysname
declare @tempDate datetime
fetch next from my_cursor1 into @nID,@date
while(@@fetch_status = 0)
begin
    set @tempDate =  dateadd(day,87,@date)
    --print @tempDate
    update Content set dtEditTime=@tempDate where nContentId = @nID
    fetch next from my_cursor1 into @nID,@date
end
close my_cursor1
deallocate my_cursor1

*/

-----------------------
DECLARE @JJ NVARCHAR(10)
SET @JJ='12345';
SET @JJ= RIGHT(@JJ,LEFT(@JJ,1))
PRINT @JJ
----------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM