对查询出来的结果集进行读取

类似于循环遍历数组,可定位

缺点:存放到TempDB里(临时表),内存有限。

适合:表数据少的时候

分类:静态,动态,只进,键值驱动游标

静态:类似于快照,支持滚动(向前向后读取都可以),数据库发生改变,结果集不变(消耗资源少)

动态:支持前后滚动,前后滚动时,结果集是重新获取一边,所以,顺序,数据都会发生改变。对数据库的改变可以通过游标可见。api函数或t-sql where current of 子句通过游标进行更新。游标外部所作的更新,直到提交才可见。(消耗资源多,不推荐)

只进:只能向前读取,不支持滚动,未读取的对数据库所做的更新在提取时是可见的,读取了就不能回头更新了。(消耗资源最少)

生命周期:声明,打开,读取,关闭,释放

下面是只进游标:

declare u_test cursor local--声明游标,,,global全局游标
for
--SQL
select * from test
where age=8
open u_test--打开游标
--声明变量
declare @u_test cursor,@id int,@uName varchar(50),@age int,@datetime varchar
set @u_test = u_test
--读取单行数值,next向下,prior向上,first第一个,last最后一个
--absolute n绝对位置,relative n从当前位置开始第n个
fetch next from u_test into @id,@uName,@age,@datetime
--循环,状态不为0
while @@FETCH_STATUS=0
begin
print convert(varchar,@id)+','+@uName+','+convert(varchar,@age);
if @id=17--单查询结果集里没id=17,哪怕数据库里有,也不会执行
update test set Tname='li',age=8 where id=19
if @id=19
update test set Tname='lio',age=8 where id=17
fetch next from u_test into @id,@uName,@age,@datetime--下一条
end
close u_test--关闭游标
deallocate u_test--释放游标
go

 

 结果:

这里的更改我使用了触发器,所以可以看出他的过程,运行到id=17时,进行更改,id=19就变了,后显示出来,运行到id=19时,虽然也对数据库进行了更改,到id=17,以及读出来了

静态游标

declare u_test_static cursor static local--声明游标,,,global全局游标
for
--SQL
select * from test
where age=8
open u_test_static--打开游标
--声明变量
declare @u_test cursor,@id int,@uName varchar(50),@age int,@datetime varchar
set @u_test = u_test_static
--读取单行数值,next向下,prior向上,first第一个,last最后一个
--absolute n绝对位置,relative n从当前位置开始第n个
fetch next from u_test_static into @id,@uName,@age,@datetime
--循环,状态不为0
while @@FETCH_STATUS=0
begin
print convert(varchar,@id)+','+@uName+','+convert(varchar,@age);
if @id=17--单查询结果集里没id=17,哪怕数据库里有,也不会执行
update test set Tname='111',age=8 where id=19
if @id=19
update test set Tname='2222',age=8 where id=17
if @id=20
fetch absolute 2 from u_test_static into @id,@uName,@age,@datetime
fetch next from u_test_static into @id,@uName,@age,@datetime--下一条
end
close u_test_static--关闭游标
deallocate u_test_static--释放游标
go

静态游标,虽然修改了数据库的信息,但当我后退去读取id=17时,那一行在静态游标的结果集没变

动态游标:

declare u_test_dynamic cursor dynamic local--声明游标,,,global全局游标
for
--SQL
select * from test
where age=8
open u_test_dynamic--打开游标
--声明变量
declare @u_test cursor,@id int,@uName varchar(50),@age int,@datetime varchar
set @u_test = u_test_dynamic
--读取单行数值,next向下,prior向上,first第一个,last最后一个
--absolute n绝对位置,relative n从当前位置开始第n个
fetch next from u_test_dynamic into @id,@uName,@age,@datetime
--循环,状态不为0
while @@FETCH_STATUS=0
begin
print convert(varchar,@id)+','+@uName+','+convert(varchar,@age);
if @id=17--单查询结果集里没id=17,哪怕数据库里有,也不会执行
update test set Tname='abc',age=8 where id=19
if @id=19
update test set Tname='efg',age=8 where id=17
if @id=20
--提取类型 Absolute 不能与动态游标一起使用。
fetch first from @u_test into @id,@uName,@age,@datetime
fetch next from u_test_dynamic into @id,@uName,@age,@datetime--下一条
end
close u_test_dynamic--关闭游标
deallocate u_test_dynamic--释放游标
go

结果集,可前后滚动,可即时获取

 

posted on 2023-04-20 11:39  阿霖找BUG  阅读(17)  评论(0编辑  收藏  举报