--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 游标名