• SQLSERVER 中的游标


    SQLSERVER 中的游标

                       在关系数据库中,传统的查询是面向结果集的,如果你想一行一行的读取数据并做相关的处理,那么你就要用到游标(像for循环一样,允许你一行一行的读取数据) 能不用游标就不用游标,在性能上,游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源,当然还有更多的代码量……

          总之:

         1.现存系统有一些游标,我们查询必须通过游标来实现

         2.作为一个备用方式,当我们穷尽了while循环,子查询,临时表,表变量,自建函数或其他方式扔来无法实现某些查询的时候,使用游标实现.游标的使用可以很简单,也可以相对复杂,取决与对游标的参数,和你对他的了解程度

       基本语法:

                    DECLARE CURSOR_NAME CURSOR 

                    LOCAL|GLOBAL

                    STATIC|KEYSET|DYNAMIC|FAST_FORWARD

                    READ_ONLY|SCROLL_LOCKS|OPTIMISTIC

                    TYPE_WARNING

                    FOR

                    SELECT * FROM TABLE

                    FOR UPDATE OF COLUMN_NAME

    接下来一一的讲解,每个参数具体的含义和使用方法。

     LOCAL 和GLOBAL 

     LOCAL 意思就是游标的生存周期只在批处理函数或存储过程中可见;

     GOBAL 意味着对于特定连接的上下文,全局内都有效的呀;

     FORWARD_ONLY 和 SCROLL 

     FORWARD_ONLY 意思就是说只能从数据集开始向结束的方向读取,FETCH NEXT是唯一的搭档;

     SCROLL  任意方向 或位置

    STATIC KEYSET DYNAMIC FAST_FORWARD

    STATIC 意思是说,当游标建立的时候,将会创建for后面的select语句所包含数据集的副本存入tempdb数据库中,任何对底层数据的更改不会影响到游标的读取。

    DYNAMIC 当底层数据更改的时候,游标的内容也随之反映上来。

    KEYSET  以理解为介于STATIC和DYNAMIC的折中方案。将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据

    FAST_FORWARD :......

    READ_ONLY SCROLL_LOCKS OPTIMISTIC

    READ_ONLY  意味着声明的游标只能读取数据,游标不能做任何更新操作

    SCROLL_LOCKS  将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功

    OPTIMISTIC 不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新

    游标的定义: 

    --定义后直接赋值
       DECLARE CUR CURSOR
       FOR
       SELECT * FROM CITYINFO
    
    --先定义后赋值
       DECLARE @CUR CURSOR
       SET @CUR=CURSOR FOR
       SELECT * FROM CITYINFO
     

    游标的打开,关闭,释放

       OPEN CURSOR_NAME       --打开游标
       
       CLOSE CURSOR_NAME       --可能会再次使用到,就暂时关闭
       
       DEALLOCATE CURSOR_NAME  --当游标不再使用的时候

    具体的实例一

        

    --定义后直接赋值
       DECLARE CUR CURSOR
       LOCAL                --本地
       STATIC               --静态
       FORWARD_ONLY         --单向
       READ_ONLY            --只读
       FOR
       SELECT NAME FROM CITYINFO
       
       OPEN CUR
       DECLARE @RESULT VARCHAR(30)
       FETCH NEXT FROM CUR INTO @RESULT
       PRINT @RESULT
       WHILE(@@FETCH_STATUS=0)  --@@FETCH_STATTIC 默认为-1 读取成功一次后为 0 读取完后 为-1 
       BEGIN                    --循环会多读取一次 出现重复
       FETCH NEXT FROM CUR INTO @RESULT
       PRINT @RESULT
       END
       
       CLOSE CUR
       DEALLOCATE CUR

      结果:(注意最后一条)

     

    具体实例二

       
     DECLARE CUR CURSOR
     LOCAL              --本地
     STATIC            --动态
     SCROLL             --滚动
     READ_ONLY          --只读
     FOR
         SELECT NAME FROM CITYINFO
     
     OPEN CUR
        DECLARE @RESULT VARCHAR(100)
        --取出下一行
        FETCH NEXT FROM CUR INTO @RESULT PRINT @RESULT
        --取出最后一行
        FETCH NEXT FROM CUR INTO @RESULT PRINT @RESULT
        --取出第一行
        FETCH FIRST FROM CUR INTO @RESULT PRINT @RESULT
        --取出上一行
        FETCH PRIOR FROM CUR INTO @RESULT PRINT @RESULT
        --取出第三行
        FETCH ABSOLUTE 3 FROM CUR INTO @RESULT PRINT @RESULT
        --取出相对目前来说的 上一行
        FETCH RELATIVE -1 FROM CUR INTO @RESULT PRINT @RESULT
        
      
        CLOSE CUR
        DEALLOCATE CUR    

    还要注意一点:    

    消息 16925,级别 16,状态 1,第 20 行
    提取类型 Absolute 不能与动态游标一起使用。

    更多的实例,还希望朋友们,自己动手测试一下。

    对于游标一些优化建议

    •      如果能不用游标,尽量不要使用游标
    •      用完用完之后一定要关闭和释放
    •      尽量不要在大量数据上定义游标
    •      尽量不要使用游标上更新数据
    •      尽量不要使用insensitive, static和keyset这些参数定义游标
    •      如果可以,尽量使用FAST_FORWARD关键字定义游标
    •      如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数
  • 相关阅读:
    使用 Rust 编写更快的 React 组件
    快速入门 postcss 插件:自动转换 px 到 rem
    通过实战理解CPU上下文切换
    “web资源加载优先级”原来能这么精准控制
    使用Brotli提高网站访问速度
    使用 npm shrinkwrap 来管理项目依赖
    如何用“底层逻辑”,看清世界的底牌?
    Node.js 应用全链路追踪技术——全链路信息获取
    解决 Elastic Search 的深分页问题
    Whistle 实现原理 —— 从 0 开始实现一个抓包工具
  • 原文地址:https://www.cnblogs.com/mc67/p/4825367.html
Copyright © 2020-2023  润新知