在做項目的過程中。我發現有許多地方有用到游標的方式去實現功能效果的。所以,整理了有關常用的實現游標的方式。 一、什麼是游標 維基百科中事這樣定義游標的。游標是處理結果集的一種機制 ,而結果集就是select查詢返回的所有行數據的集合。 對於我而言,用通俗的話來講,就是把自己需要用到的數據先放到一個容 ...
前言
在做項目的過程中。我發現有許多地方有用到游標的方式去實現功能效果的。所以,整理了有關常用的實現游標的方式。
什麼是游標
維基百科中事這樣定義游標的。游標是處理結果集的一種機制 ,而結果集就是select查詢返回的所有行數據的集合。
對於我而言,用通俗的話來講,就是把自己需要用到的數據先放到一個容器裡面,然後迴圈遍歷這個容器裡面的所有行和列的一個操作。
游標的用處
1.定位到結果集中的某一行。
2.對當前位置的數據進行讀寫。
3.可以對結果集中的數據單獨操作。而不是整行執行操作。
游標的分類
1.靜態游標:操作之後,靜態游標中select的數據依舊顯示的為沒有操作之前的數據。
2.動態游標:所有用戶做的增刪改語句通過游標均可見。如果使用API函數或T-SQL Where Current of子句通過游標進行更新,他們將立即可見。
3.只進游標:只進游標不支持滾動,只支持從頭到尾順序提取數據,資料庫執行增刪改,在提取時是可見的,但由於該游標只能進不能向後滾動,
所以在行提取後對行做增刪改是不可見的。
游標的生命周期
游標的生命周期包含五個階段:聲明游標,打開游標,讀取游標數據,關閉游標,釋放游標。
游標的語法
無事務游標的語法
1.創建存儲過程
create proc [存儲過程名稱] as
declare --臨時變數,用來保存游標值
@[參數] 參數類型,
@error int --記錄每次運行sql後是否正確,0是正確。
set @error=0
--2.聲明游標
declare [游標名稱] cursor for
--3.需要迴圈的結果集
select [列名] from [表明] where [條件];
--4.打開游標
open [游標名稱]
--5.開始迴圈游標變數
fetch next from [游標名稱] into @[參數]
--6.返回被 FETCH 語句執行的最後游標的狀態,而不是任何當前被連接打開的游標的狀態。
while(@@fetch_status=0)
begin
begin
--執行操作邏輯
end
set @error= @error + @@ERROR --記錄每次運行sql後是否正確,0正確
--開始迴圈游標變數
fetch next from [游標名稱] into @[參數]
end
--7.關閉游標
close [游標名稱]
--8.釋放游標
deallocate [游標名稱]
--執行創建存儲過程
exec [存儲過程名稱]
帶事務的游標寫法
1.創建存儲過程
create proc [存儲過程名稱] as
declare --臨時變數,用來保存游標值
@[參數] 參數類型,
@error int --記錄每次運行sql後是否正確,0是正確。
set @error=0
begin tran
--2.聲明游標
declare [游標名稱] cursor for
--3.需要迴圈的結果集
select [列名] from [表名] where [條件];
--4.打開游標
open [游標名稱]
--5.開始迴圈游標變數
fetch next from [游標名稱] into @[參數]
--6.返回被 FETCH 語句執行的最後游標的狀態,而不是任何當前被連接打開的游標的狀態。***
while(@@fetch_status=0)
begin
begin
--執行操作邏輯
end
set @error= @error + @@ERROR --記錄每次運行sql後是否正確,0正確
--開始迴圈游標變數
fetch next from [游標名稱] into @[參數]
end
if @error=0
begin
commit tran --提交事務
end
else
begin
rollback tran --回滾事務
end
--7.關閉游標
close [游標名稱]
--8.釋放游標
deallocate [游標名稱]
--執行創建存儲過程
exec [存儲過程名稱]
例子
需求 當執行狀態是執行中,到時間自動完成。記錄中狀態是執行中變為已完成,並更新時間。
創建SysStatus表
create table SysStatus
(
id uniqueidentifier primary key default(newid()) NOT NULL, --主鍵
opuer nvarchar(50) NULL, --操作人
opstatus nvarchar(50) NULL, --操作狀態
applytime datetime default(getdate()) NULL, --申請時間
updatetime datetime NULL --更新時間
)
插入數據
編寫游標的存儲過程
無事務的游標
create proc pro_curror as
declare
@id uniqueidentifier, --聲明表主鍵變數
@error int --記錄每次運行sql後是否正確,0是正確。
set @error=0
--2.聲明游標
declare y_curr cursor for
--3.需要迴圈的結果集
select id from SysStatus where opstatus='執行中' and applytime<GETDATE();
--4.打開游標
open y_curr
--5.開始迴圈游標變數
fetch next from y_curr into @id
--6.返回被 FETCH 語句執行的最後游標的狀態,而不是任何當前被連接打開的游標的狀態。***
while(@@fetch_status=0)
begin
begin
update SysStatus set opstatus='已完成',updatetime=getdate() where id=@id;
end
set @error= @error + @@ERROR --記錄每次運行sql後是否正確,0正確
--開始迴圈游標變數
fetch next from y_curr into @id
end
--7.關閉游標
close y_curr
--8.釋放游標
deallocate y_curr
--執行創建存儲過程
exec pro_curror
執行存儲過程前:
執行存儲過程後:
有事務的游標
create proc pro_curror_tran as
declare
@id uniqueidentifier, --聲明表主鍵變數
@error int --記錄每次運行sql後是否正確,0是正確。
set @error=0
begin tran
--2.聲明游標
declare y_curr cursor for
--3.需要迴圈的結果集
select id from SysStatus where opstatus='執行中' and applytime<GETDATE();
--4.打開游標
open y_curr
--5.開始迴圈游標變數
fetch next from y_curr into @id
--6.返回被 FETCH 語句執行的最後游標的狀態,而不是任何當前被連接打開的游標的狀態。***
while(@@fetch_status=0)
begin
begin
update SysStatus set opstatus='已完成',updatetime=getdate() where id=@id;
end
set @error= @error + @@ERROR --記錄每次運行sql後是否正確,0正確
--開始迴圈游標變數
fetch next from y_curr into @id
end
if @error=0
begin
commit tran --提交事務
end
else
begin
rollback tran --回滾事務
end
--7.關閉游標
close y_curr
--8.釋放游標
deallocate y_curr
--執行創建存儲過程
exec pro_curror_tran
執行存儲過程前:
執行存儲過程後: