在做项目的过程中。我发现有许多地方有用到游标的方式去实现功能效果的。所以,整理了有关常用的实现游标的方式。
一、什么是游标
维基百科中事这样定义游标的。游标是处理结果集的一种机制 ,而结果集就是select查询返回的所有行数据的集合。
对于我而言,用通俗的话来讲,就是把自己需要用到的数据先放到一个容器里面,然后循环遍历这个容器里面的所有行和列的一个操作。
二、游标的用处
1.定位到结果集中的某一行。
2.对当前位置的数据进行读写。
3.可以对结果集中的数据单独操作。而不是整行执行操作。
三、游标的分类
1.静态游标:操作之后,静态游标中select的数据依旧显示的为没有操作之前的数据。
2.动态游标:所有用户做的增删改语句通过游标均可见。如果使用API函数或T-SQL Where Current of子句通过游标进行更新,他们将立即可见。
3.只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
四、游标的生命周期
游标的生命周期包含五个阶段:声明游标,打开游标,读取游标数据,关闭游标,释放游标。
五、游标的语法
1)、无事务游标的语法
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 [存储过程名称]
2)、带事务的游标写法
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 [存储过程名称]
例子
需求 当执行状态是执行中,到时间自动完成。记录中状态是执行中变为已完成,并更新时间。
1.创建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 --更新时间
)
2.插入数据
3.编写游标的存储过程
- 无事务的游标
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
执行存储过程前:
执行存储过程后:
2)有事务的游标
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
执行存储过程前:
执行存储过程后: