SQL游标

--SQL Server支持的API服务器游标分为一下4种
--1静态游标: 静态游标的结果集,在游标打开的时候建立在TempDB中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。例如你在游标打开的时候,对游标查询的数据表数据进行增删改,操作之后,静态游标中select的数据依旧显示的为没有操作之前的数据。如果想与操作之后的数据一致,则重新关闭打开游标即可。
--2动态游标:这个则与静态游标相对,滚动游标时,动态游标反应结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游标均可见。如果使用API函数或T-SQL Where Current of子句通过游标进行更新,他们将立即可见。在游标外部所做的更新直到提交时才可见。
--3只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
--4键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如insert一条数据,是不可见的,若可见,须关闭重新打开游标。

--只有出现在游标中的SELECT语句中的列才能作为ORDER BY 子句的排序列,而对与非游标的SELECT语句中,表中任何列都可以作为ORDER BY 的排序列,即使该列没有出现在SELECT语句的查询结果列中。

--通过检测全局变量@@Fetch_Status的值,获得提取状态信息,该状态用于判断Fetch语句返回数据的有效性。当执行一条Fetch语句之后,@@Fetch_Status可能出现3种值:0,Fetch语句成功。-1:Fetch语句失败或行不在结果集中。-2:提取的行不存在。
--使用系统全局变量 @@cursor_rows 查询游标中结果集中的行数:
--n:表示返回的实际行数。
---1:表示游标是动态的。
--0:表示空集游标。

--游标定义语法
declare cursor_name cursor [ local | global ] 
     [ forward_only | scroll ] 
     [ static | keyset | dynamic | fast_forward ] 
     [ read_only | scroll_locks | optimistic ] 
     [ type_warning ] 
     for select_statement 
     [ for update [ of column_name [ ,...n ] ] ]


--cursor_name:是所定义的t_sql 服务器游标的名称。

--local:对于在其中创建批处理、存储过程或触发器来说,该游标的作用域是局部的。

--global:指定该游标的作用域是全局的

--forward_only:指定游标只能从第一行滚动到最后一行。fetch next是唯一支持的提取选项,如果在指定forward_only时不指定static,keyset和dynamic关键字,则游标作为dynamic游标进行操作,如果forward_only和scroll均为指定,则除非指定static,keyset和dynamic关键字,否则默认为forward_only。static,keyset和dynamic游标默认为scroll。与odbc和ado这类数据库api不同,static,keyset和dynamic t_sql游标支持forward_only。
--static:定义一个游标,以创建将又该游标使用的数据临时复本,对游标的所有请求都从tempdb中的这以临时表中不得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。
--keyset:指定当游标打开时,游标重的行的成员身份和顺序已经固定。对行进行唯一标识的键值内置在tempdb内一个称为keyset的表中。
--dynamic:定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改,动态游标不支持absolute提取选项。
--fast_forward:指定启动了性能优化的forward_only、read_only游标。如果指定了scroll或for_update,则不能指定fast_forward。
--scroll_locks:指定通过游标进行的定位更新或删除一定会成功。将行读入游标时sql server将锁定这些行,以确保随后可对它们进行修改,如果还指定了fast_forward或static,则不能指定scroll_locks。
--optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sql server不锁定行,它改用timestamp列值比较结果来确定行读入游标后是否发生了修改,如果表不包含timestamp列,它改用校验和值进行确定,如果以修改该行,则尝试进行的定位更新或删除将失败,如果还指定了fast_forward,则不能指定optimistic。
--type_warning:指定游标从所请求的类型隐式转换为另一种类型时,向客户端发送警告消息。
--select_statement:是定义游标结果集中的标准select语句。




--打开游标的语法如下:open [ global ] cursor_name | cursor_variable_name;

--global:指定cursor_name是全局游标。

--cursor_name:已声明的游标的名称。如果全局游标和局部游标都使用cursor_name作为其名称,那么如果指定了global,则cursor_name指的是全局游标,否则cursor_name指的是局部游标。

--cursor_variable_name:游标变量的名称。


--读取游标中的数据
etch 
[ [ next | prior | first | last 

         | absolute { n | @nvar }

         | relative { n | @nvar }
    ]
from
]
{ { [global ] cursor_name } | @cursor_variable_name}
[ into @variable_name [ ,...n ] ]

--next:紧跟当前行返回结果行,并且当前行递增为返回行,如果fetch next为对游标的第一次提取操作,则返回结果集中的第一行。next为默认的游标提取选项。
--prior:返回紧邻当前行前面的结果行,并且当前行递减为返回行,如果fetch prior为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。
--first:返回游标中的第一行并将其作为当前行。
--last:返回游标中的最后一行并将其作为当前行。
--absolute { n | @nvar }:如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.
--relative { n | @nvar }:如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定fetch relative,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.
--global:指定cursor_name是全局游标
--cursor_name:已声明的游标的名称。如果全局游标和局部游标都使用cursor_name作为其名称,那么如果指定了global,则cursor_name指的是全局游标,否则cursor_name指的是局部游标。
--@cursor_variable_name:游标变量名,引用要从中进行提取操作的打开的游标。
--into @variable_name [ ,...n ]:允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果集列的数据类型相匹配,或是结果集列数据类型所支持的隐士转换。变量的数目必须与游标选择列表中的列数一致。


--关闭游标
close [ global ] cursor_name | cursor_variable_name

--释放游标
deallocate [global] cursor_name | @ccursor_variable_name

@ccursor_variable_name:游标变量的名称,@ccursor_variable_name必须为cursor类型deallocate @ccursor_variable_name 语句只删除对游标变量名称的引用,直到批处理、存储过程或触发器结束时变量离开作用域,才释放变量。



五、游标

declare @ID int
declare @Oid int
declare @Login varchar(50) 
  
--定义一个游标 
declare user_cur cursor for select ID,Oid,[Login] from ST_User 
--打开游标 
open user_cur 
while @@fetch_status=0 
begin
--读取游标 
    fetch next from user_cur into @ID,@Oid,@Login 
    print @ID 
    --print @Login 
end
close user_cur 
--摧毁游标 
deallocate user_cur


declare @OrderId int
fetch absolute 3 from orderNum_02_cursor into @OrderId
while @@fetch_status=0  --提取成功,进行下一条数据的提取操作
 begin
   select @OrderId as id
   fetch  next from orderNum_02_cursor into @OrderId  --移动游标
 end 


 --利用游标更新删除数据 
 --游标修改当前数据语法
update 基表名 set 列名=[,...] where current of 游标名
--游标删除当前数据语法
delete 基表名  where current of 游标名

 

posted @ 2019-04-11 23:24  唧唧复唧唧木兰当户织  阅读(543)  评论(0编辑  收藏  举报