SqlServer 总结(1) 游标

前言

在做项目的过程中。我发现有许多地方有用到游标的方式去实现功能效果的。所以,整理了有关常用的实现游标的方式。

什么是游标


维基百科中事这样定义游标的。游标是处理结果集的一种机制 ,而结果集就是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

执行存储过程前:

执行存储过程后:

原文地址:https://www.cnblogs.com/ZengJiaLin/p/11130838.html