首页 > 数据库 >SQL Server 游标

SQL Server 游标

时间:2023-05-25 20:55:58浏览次数:32  
标签:定义 游标 Server ONLY SQL FORWARD 数据 FETCH

@@SQL server 游标

 

SQL Server 游标

游标
游标是邪恶的!在关系数据库中, 查询是面向集合的,而游标打破了这个规则, 游标是面向记录的(行),正确的面向集合的思维方式是这样的

 

 

而对于游标来说

 

 

 

这也就是为什么游标是邪恶的,同样的, 在性能上,游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源,更多的代码量
从游标读取数据的方式不难看出为什么占用更多的资源,比如:当你从ATM里一次取1000效率高呢?还是10次取100快?

既然游标是邪恶的,为什么我们还要学习游标呢?
存在即合理,就像前面说的,IN与NOT IN是无视索引的,会引发查询一系列的隐藏问题,但是就是有它自己的用处。当我们穷尽了WHILE和子查询或者其他条件仍然无法完成查询的效果,就可以使用游标来实现

T-SQL中游标的生命周期以及实现
游标由5个部分组成
1.定义一个游标
在T-SQL,定义一个游标可以是很简单的,也可以是复杂的,取决于游标的参数,而游标的参数设置决定了你对游标原理的理解程度
游标其实可以理解为一个定义在特定 数据集上的指针(如果对数据集的概念不理解可以看上一篇文章),我们可以控制这个指针遍历数据集,或者指向特定行,所以游标是在以SELECT开始的数据集上的

DECLARE cursor_name CURSOR [ LOCAL | GLOBAL](作用域)
[FORWARD_ONLY | SCROLL](方向)
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD](类型)
[READ_ONLY | SCROLL_LOCK | OPTIMISTIC]
[TYPE_WARNING]
FOR SELECT col1,col2 FROM table_name

 


下面就仔细讲一下这句语句的意义

游标分为全局游标和局部游标,对于局部游标来说,遵循T-SQL变量的定义方法(变量的定义可以参考前面文章),局部游标变量支持两种方式赋值,定义时候赋值,或者先定义后赋值,定义时要在游标名前面加‘@’,如果定义全局游标,就不用加‘@’,只支持定义时直接赋值

 

 

下面讲参数的选择:

LOCAL和GLOBAL二选一

LOCAL意味着游标的s生存周期只在批处理,函数或者存储过程中可见,类似局部变量,而GLOBAL在在整个会话窗口中可见,全局有效

如果不指定作用域,默认为GLOBAL

 

 

FORWARD_ONLY和SCROLL二选一

FORWARD_ONLY意味着游标只能从数据集开始的地方向数据集结束的地方的方向读取,FETCH NEXT 为唯一选项。而SCROLL支持游标在定义的数据集中向任何方向或者任何位置移动。不加参数则默认为FORWARD_ONLY

 

 

STATIC,KEYSET,DYNAMIC和FAST_FORWARD四选一

这四个关键字表示游标所在数据集所反映的表内数据与游标读取的数据关系

STATIC:当游标被创建时,将会创建FOR后面的SELECT语句所包含数据集的副本存到tempdb数据库中,任何底层表内的数据的更改都不会影响到游标的内容

DYNAMIC:是和STATIC相反的极端,当底层数据库被更改时,游标的内容也会跟着得到反应,在下一次FETCH中,数据内容也会跟着改变

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

FAST_FORWARD:可以理解为FORWARD_ONLY的优化版,FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况来选择动态计划还是静态计划,大多数情况下FAST_FORWARD的性能要比FORWARD_ONLY略好

READ_ONLY,SCROLL_LOCKS和OPTIMISTIC三选一

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

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

OPTIMISTIC:相对来说比较好一点的选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果底层数据未更新,则游标表内数据可以更新。

2.打开游标

定义完游标后,使用OPEN cursor_name即可以打开游标

3.读取游标数据

游标的使用分为两部分,一部分是操作游标在数据集内的指向,另一部分是将游标所指向的部分行或者全部行进行操作

6种移动方式:第一行(FIRST),最后一行(LAST),下一行(NEXT),上一行(PRIOR),直接跳向某行(ABSOLUTE n),相对于目前行的第几行(RELATIVE n)

 

 

游标经常会与全局变量@@FETCH_STATUS与WHILE循环配合使用,以达到遍历游标所在的数据集的目的

 

 

4.关闭游标
使用完游标后要关闭游标:CLOSE cursor_name
5.释放游标
当游标不再使用了一定要释放游标:DEALLOCATE cursor_name
全局变量@@FETCH_STATUS
每执行一个FETCH后,都会返回一次@@FETCH_STATUS状态值,判断FETCH是否执行成功
0:表示成功执行FETCH
-1:表示FETCH语句失败,例如移动指针使其超出的结果集
-2:表示被提取的行不存在
建议
如果能不用游标就别用,游标永远是无奈下的选择,是一种非常邪恶的存在,面向记录的特性会比面向集合的特性慢上很多倍
用完一定要关闭与释放
有大量数据的时候不要用游标
尽量不要用游标更新数据
尽量不要使用INSENSITIVE,STATIC和KEYSET这些参数定义游标,因为占用了其他空间
如果可以,尽量使用FAST_FORWARD关键字定义游标
如果只对数据进行读取,当读取只用到FETCH NEXTx选项,最好使用FORWARD_ONLY参数
————————————————
版权声明:本文为CSDN博主「纪智坚」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43888054/article/details/127228131

标签:定义,游标,Server,ONLY,SQL,FORWARD,数据,FETCH
From: https://www.cnblogs.com/wl-blog/p/17432904.html

相关文章

  • MySQL存储引擎精简版
    存储引擎简介概念:其是存储数据,建立索引,更新查询数据等操作的技术支持,引擎是基于表的,所以又称表结构常见分类InnoDBMySQL5.5之后默认引擎特点:1.操作遵循ACID原则,支持事务2.支持行锁3,支持外键约束MyISAMMySQL早期默认引擎特点:1.不支持事务和外键约束,支持表锁......
  • mysql语言
    DQL:数据查询语言->数据select+from+whereDML:数据操作语言->数据insert、update、deleteDDL:数据定义语言->数据库对象(数据库,表,索引,触发器,存储过程,函数)createalter:修改数据库对象dropDCL:数据控制语言grant:授予用户某种权限revoke:回收授予的某种权限TCL:事物控制语言star......
  • MySQL索引高级进阶详解-玩转MySQL数据库
    前言从今天开始本系列文章就带各位小伙伴学习数据库技术。数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深,全面讲解数据库体系。非常适合零基础的小伙伴来学习。全文大约【1957】字,不说废话,只讲可以让你学到技术、明白原理的纯干......
  • MySQL索引
    一、索引介绍1、索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。2、优缺点:使用索引可以大大加快数据的检索速度(大大减少检索的数据量),这也是创建索引的最主要的原因创建索引和维护索引需要耗费许多时间。索引需要使用物理文件存储,也会......
  • ORACLE表空间使用量查询SQL
    SELECTUpper(F.TABLESPACE_NAME)AS表空间名,round(D.TOT_GROOTTE_MB/1024,2)AS"总大小(G)",round((D.TOT_GROOTTE_MB-F.TOTAL_BYTES)/1024,2)AS"已使用空间(G)",round(F.TOTAL_BYTES/1024,2)AS"空闲空间(G)",R......
  • LINUX下定时备份MYSQL数据库SHELL脚本
    备份脚本backupMysqlData.sh#!/bin/bash#备份SQL文件的路径backupdir=/home/hdkg/mysqldata/#执行导出数据库操作mysqldump--user=root--password=password--host=localhost--port=3306dataBaseName>$backupdir/backupfile_$(date+%Y%m%d).sql#删除七天前的备份数......
  • 两个MYSQL数据同步的SHELL脚本
    #/!bin/bashHOST=127.0.0.1#ip(127.0.0.1表示本机地址)USER=root#数据库用户名PASSWORD=password#数据库密码DATABASE=pig#数据库名BACKUP_PATH=/home/hdkg/bkdata/#备份目录logfile=/home/hdkg/bklog/data.log#记录日志TABLES="testtest......
  • 使用DataX从ORACLE同步数据到MYSQL
    [前提]安装python3.7oracle版本:oracle11gmysql版本:mysql5.71.下载DataXwgethttp://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz2.解压DataXtar-zxvfdatax.tar.gz3.编写同步脚本进入dataXbin目录cd${HOME目录}/datax/bin 编写同步脚本vioracleToMysql.json......
  • mybatis-plus控制台打印SQL
    方法一、在application.yml添加配置#mybatis-plus配置控制台打印完整带参数SQL语句mybatis-plus:configuration:log-impl:org.apache.ibatis.logging.stdout.StdOutImpl方法二、mapper增加日志等级为debuglogging:level:com.chz.mapper:debug ......
  • SqlSever表结构转C#实体类
    declare@TableNamesysname='repair_plan'declare@Resultvarchar(max)='///<summary>///'+@TableName+'///</summary>publicclass'+@TableName+'{'select@Result=@Result+'///......