zoukankan      html  css  js  c++  java
  • 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
    
    

    执行存储过程前:

    执行存储过程后:

  • 相关阅读:
    关于Java常见的误解
    Java程序设计概述
    是结束,更是开始!
    从零开始单排学设计模式「简单工厂设计模式」黑铁 III
    某神秘公司 RESTful、共用接口、前后端分离、接口约定的实践
    这40张图送给单身程序员,情人节请一笑而过!
    科技圈晒开工福利!2019一起定个小目标!
    IDEA一定要懂的32条快捷键
    假期结束了,我相信未来会更好!
    有一种痛,叫 “今年没有年终奖”!!!
  • 原文地址:https://www.cnblogs.com/ZengJiaLin/p/11130838.html
Copyright © 2011-2022 走看看