sql server 中游标详解
Posted dreamw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql server 中游标详解相关的知识,希望对你有一定的参考价值。
@@SQL server 游标
目录
游标的定义
种类:(我也不太理解,有理解的@我)
游标的类型:
游标的实现
游标的实现功能
游标的使用的步骤:
游标的使用:
1.声明游标
游标的格式:(看了很多版本的格式说明, 这是最好理解的)
声明一个动态游标:
2.打开游标
3读取数据
读取数据的格式:
读取数据:
4.关闭游标
格式:
关闭游标:
5.释放游标
格式:
释放游标:
补充关于游标的几个变量:
游标的定义
定义:算了, 我按照自己理解说吧,
除了where 语句能选出一个特定的结果集, 但是我要是对这个结果集,对这个结果集进行逐条操作, 是没有这个功能的, 那么游标就可以实现这个操作,
游标说白了, 就是我先取一个结果集,然后后对这个结果集逐条进行操作!!!!!
种类:(我也不太理解,有理解的@我)
MS SQL SERVER 支持三种类型的游标:Transact_SQL 游标,API服务器游标和客户游标。
(1)Transact_SQL 游标
Transact_SQL 游标是由DECLARE CURSOR 语法定义、主要用在Transact_SQL脚本、存储过程和触发器中。Transact_SQL 游标主要用在服务器上,由从客户端发送给服务器的Transact_SQL 语句或是批处理、存储过程、触发器中的Transact_SQL 进行管理。Transact_SQL 游标不支持提取数据块或多行数据。
(2)API游标
API 游标支持在OLE DB, ODBC 以及DB_library 中使用游标函数,主要用在服务器上。每一次客户端应用程序调用API 游标函数,MS SQL SEVER 的OLE DB 提供者、ODBC驱动器或DB_library 的动态链接库(DLL) 都会将这些客户请求传送给服务器以对API游标进行处理。
(3)客户游标
客户游标主要是当在客户机上缓存结果集时才使用。在客户游标中,有一个缺省的结果集被用来在客户机上缓存整个结果集。客户游标仅支持静态游标而非动态游标。由于服务器游标并不支持所有的Transact-SQL语句或批处理,所以客户游标常常仅被用作服务器游标的辅助。因为在一般情况下,服务器游标能支持绝大多数的游标操作。由于API 游标和Transact-SQL 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。
游标的类型:
根据游标检测结果集变化的能力和消耗资源的情况不同,SQL Server支持的API服务器游标分为一下4种:
静态游标 : 静态游标的结果集,在游标打开的时候建立在TempDB中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。例如你在游标打开的时候,对游标查询的数据表数据进行增删改,操作之后,静态游标中select的数据依旧显示的为没有操作之前的数据。如果想与操作之后的数据一致,则重新关闭打开游标即可。(静态游标,不会随着数据表的更新而更新,消耗资源少)
动态游标 : 这个则与静态游标相对,滚动游标时,动态游标反应结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游标均可见。如果使用API函数或T-SQL Where Current of子句通过游标进行更新,他们将立即可见。在游标外部所做的更新直到提交时才可见。(动态游标随着数据表的更新而更新,不过消耗资源大)
只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。(只进游标,就是按着顺序逐行进行读取, 不能重复读取,不能回头在查 )
键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如insert一条数据,是不可见的,若可见,须关闭重新打开游标。静态游标在滚动时检测不到表数据变化,但消耗的资源相对很少。动态游标在滚动时能检测到所有表数据变化,但消耗的资源却较多。键集驱动游标则处于他们中间,所以根据需求建立适合自己的游标,避免资源浪费。(这个游标呢, 就是只监控你当时取得结果集, 你修改这个结果集中的数据我就更新结果集, 你往数据表中添加新数据, 不好意思, 没有在我的监控范围, 我只管我该管的, 这样消耗资源介于静态和动态游标之间)
游标的实现
游标可以干那些活呢?
游标的实现功能
允许对 SELECT 返回的表中的每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;
从表中的当前位置检索一行或多行数据;
游标允许应用程序对当前位置的数据进行修改、删除的能力;
对于不同用户对结果集包含的数据所做的修改,支持不同的可见性级别;
提供脚本、存储过程、触发器中用于访问结果集中的数据的语句
说了这么多概念, 还是来点你感兴趣
游标的使用的步骤:
1.声明游标
2.打开游标
3,冲游标中读取数据
4关闭游标
5释放游标
游标的使用:
1.声明游标
游标的格式:(看了很多版本的格式说明, 这是最好理解的)
DECLARE 游标名称 CURSOR
[ LOCAL | GLOBAL ] --游标的作用域
[ FORWaRD_ONLY | SCROLL ] --游标的移动方向
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] --游标的类型
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] --游标的访问类型
[ TYPE_WARNING] --类型转换警告语句
FOR SELECT 语句 --SELECT查询语句
[ FOR READ ONLY | UPDATE [OF 列名称]][,...n] --可修改的列
现在我哦们进行解剖格式:
1)游标的作用域
local:本地游标(默认的),会随着批处理的解释而释放
global:全局游标,全局的游标,只要有需要我就可以让你用, 你不用, 我再隐性释放(不是真的释放了)
2)游标的移动:
forward_only: 这个可以理解为止进游标, 与游标的种类无关, 只能重第一行开始,逐条进行读取数(
当我不指定游标类型(static , dynamic keyset)的时候,默认是forward_only),读取方式呢只能用 next
scroll:游标可以会滚操作,指定游标类型,默认是;
3)游标的类型
static :静态游标,结果集不随着数据表的更新而更新;
dynamic :动态游标,结果集随着数据表的更新而更新;
keyset:我只监控我结果集范围内的数据的更新, 不监控我看不到的
再来说一下这个fast_forward ,这个关键字我感觉不应该放在这里, 极其让人容易误解,这个不是游标的种类, 而是一种组合, 等价于forward_only和read_only的一中组合表现形式
4)游标的访问类型
read_only :设置为只读属性的游标, 不能进行数据更新
scroll_locks:将行读入游标时,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他
5) 类型转换警告:
Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
6)可更改的列
For Update[of column_name ,....] :定义游标中可更新的列。
声明一个动态游标:
--declare @d1 cursor ;
declare emp_cur cursor scroll
dynamic --默认的
for select * from emp
--set @d1 = emp_cur
注释的是想让大家知道, 游标也可以当作一个变量去赋值操作:
2.打开游标
--open 游标名字
open emp_cur;
3读取数据
读取数据的格式:
Fetch
[ Next|prior|Frist|Last|Absoute n|Relative n ]
from
cursor_name
[into @variable_name[,....]]
解读格式
Frist:结果集的第一行
Prior:当前位置的上一行
Next:当前位置的下一行
Last:最后一行
Absoute n:从游标的第一行开始数,第n行。
Relative n:从当前位置数,第n行。
Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。
读取数据:
fetch next from emp_cur
4.关闭游标
格式:
close cursor_name;
关闭游标:
close emp_cur
5.释放游标
格式:
deallocate emp_cur
释放游标:
deallocate emp_cur
补充关于游标的几个变量:
1.@@Fetch_Status:获得提取状态信息,该状态用于判断Fetch语句返回数据的有效性;!主要用于游标读取做循环操作;
0,Fetch语句成功。
-1:Fetch语句失败或行不在结果集中。
-2:提取的行不存在。
2.全局 变量 @@CORSOR_ROWS 用来记录游标内的数据行数。返回值有四种:全局 变量 @@CORSOR_ROWS 用来记录游标内的数据行数。返回值有四种:
返回值 描述
-m 表示仍在从基础表向游标读入数据,m表示当前在游标中的数据行数
-1 该游标是一个动态游标,其返回值无法确定
0 无符合调剂的记录或游标已经关闭
n 从基础表向游标读入数据已结束,n 为游标中已有的数据记录行数
好了, 就是我对于游标的理解与总结 ;
关于在例子中使用的数据在我的别的文章中有脚本
创建数据的脚本
————————————————
版权声明:本文为CSDN博主「guokeeiron」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guokeeiron/article/details/130003298
sql server中如何判断游标是否存在
--测试 DECLARE @SNAME VARCHAR(20) DECLARE DD CURSOR FOR SELECT SNAME FROM S OPEN DD --楼上说的对.你要的是判断游标是否存在 select * from MASTER.dbo.syscursors where cursor_name='DD' --以下操作为判断游标是否存在的同时检测游标状态。 SELECT (CASE WHEN CURSOR_STATUS('global','DD')=1 THEN '游标的结果集至少有一行' WHEN CURSOR_STATUS('global','DD')=0 THEN '游标的结果集为空' WHEN CURSOR_STATUS('global','DD')=-1 THEN '游标被关闭' WHEN CURSOR_STATUS('global','DD')=-2 THEN '游标不适用' WHEN CURSOR_STATUS('global','DD')=-3 THEN '游标不存在' END) AS RESULT /*返回结果: 1 游标的结果集至少有一行。 对于不区分的游标和键集游标,结果集至少有一行。 对于动态游标,结果集可以有零行、一行或多行。 分配给该变量的游标已打开。 对于不区分的游标和键集游标,结果集至少有一行。 对于动态游标,结果集可以有零行、一行或多行。 0 游标的结果集为空。* 分配给该变量的游标已经打开,然而结果集肯定为空。* -1 游标被关闭。 分配给该变量的游标被关闭。 -2 不适用。 可以是: 先前调用的过程并没有将游标分配给 OUTPUT 变量。 先前调用的过程为 OUTPUT 变量分配了游标,然而在过程结束时,游标处于关闭状态。因此,游标被释放,并且没有返回调用过程。 没有将游标分配给已声明的游标变量。 -3 具有指定名称的游标不存在。 具有指定名称的游标变量并不存在,或者即使存在这样一个游标变量,但并没有给它分配游标。
以上是关于sql server 中游标详解的主要内容,如果未能解决你的问题,请参考以下文章