什么是游标?
一个对表进行操作的T-SQL语句通常都可产生或处理一组记录,但是许多应用程序,尤其是T-SQL的嵌入的主语言,通常不能把整个结果集作为一个单元来处理。这些应用程序就需要一种机制来保证每次处理结果集中的一行或者多行,游标(cursor)就提供了这种机制
在SQL Server中,有两类游标可以用于应用程序中:前端(client)游标和后端(server)游标。服务器端游标是由数据库创建和管理的游标,而客户端游标是由ODBC和DB-Library支持,在客户端实现的游标。同时,他完全支持通过服务器游标的游标操作,所以应尽量不使用客户端游标
使用游标的规则
SQL Server 对游标的使用要遵循:声明游标–打开游标–读取数据–关闭游标-删除游标
声明游标
T-SQL中声明游标使用declare cursor
语句,该语句有两种格式,分别支持SQL92标准和T-SQL扩展的游标标准
SQL-92写法
declare cursor_name [insensitive][scroll] cursor
for select 语句
[for {read only|update[of column_name[,...]}]
SQL-92格式说明
语句 | 说明 |
---|---|
cursor_name | 您要创建的游标名,它是与某个结果集想联系的符号名,要符合SQL server标识命名规范 |
insensitive | 指定系统将创建供所定义的游标使用使用数据的临时副本,对有所有的请求都从tempdb中的该临时表中得到应答。因此,在对该游标进行提取操作时返回的数据不反映对基本表所做的修改,并且该游标不允许修改。如果省略了insensitive,则任何用户对基本表所提交的删除和更新都将反映在后面的提取中 |
scroll | 所声明的游标可以前滚,后滚,fetch语句可使用的所有的提取选项(first,last,prior,next,relative,absolute),如果省略了scroll关键字,则只能使用next提取选项 |
select语句 | 由该查询与所声明的游标相关联的结果集 |
read only | 说明所声明的游标为只读 |
update | 指定游标中可以更新的列。若有参数of column_name[,…],则只能修改给出的这些列;若在update中未指出列,则可以修改所有列 |
例子:定义一个符合SQL92标准的游标
use test1;
go
declare curl cursor
for
select 学号,姓名,性别,出生日期,专业,总学分
from xsb
where 性别=1
for read only
go
T-SQL扩展写法
declare 游标名 cursor
[local|global] /*游标作用域*/
[forward_only|scroll] /*游标的移动方向*/
[static|keyset|dynamic|fast_forward] /*游标类型*/
[read_only|scroll_locks|opmistic] /*访问属性*/
[type_warning] /*类型转换警告*/
for select 语句 /*select查询语句*/
[for update [of[列名,...]]] /*可修改的列*/
T-SQL扩展说明
语句 | 说明 |
---|---|
游标作用域 | 游标作用域有(本地)local和(全局)global两种;local所声明的游标为局部游标,其作用域为创建它的批处理,储存对象或者触发器等对象。在这些对象的output参数中,该游标可由局部游标变量引用,在这些对象终止时,该游标就自动释放。但是如果output参数将游标传递回来,则游标仍可以使用:global所声明的游标为全局游标,它在有连接的任何储存过程或者批处理中都可以使用,在连接时释放,游标自动释放。若是两者均为指定,则有default to local cursor数据库选项的设置控制 |
游标的移动方向 | forward_only与scroll;forward_only说明游标只支持从第一行翻滚到最后一行,即该游标只能支持fetch的next提取选项 ;scroll支持游标的所有移动方式 |
游标类型 | static静态游标;dynamic动态游标;keyset键值对游标;fast_ward快速只进游标 |
访问属性 | read_only说明游标为只读游标,不能通过该游标更新数据;scroll_locks关键字说明通过游标完成的定位更新或者。(相当于线程锁);optimstic的含义游标是将数据读取以后,如果这些数据被更新了,则通过游标定位更新与删除操作都不会成功 |
类型转换警告 | type_warning |
例子:
use test1;
go
declare name1 cursor
local
scroll
dynamic
scroll_locks
type_warning
for select * from table1
for update
打开游标
声明游标后,要使用游标从中提取游标数据,就必须先打开游标。其格式为:
open{{[global]游标名}|游标变量名}
说明:
- open打开游标,执行游标定义语句中指定的T-SQL语句来填充游标(即生成与游标相关联的结果集)
- 如果所打开的是静态游标(insensitive或者static关键字定义游标),那么将创建一个临近表以保存结果集; 如果所打开的是键值驱动游标(使用keyset关键字),那么将创建一个临时表以保存键集。临时表都储存在tempdb数据库中
- 打开游标后,可以使用全局变量@@cursor_rows查看游标中数据行的数目。当其值为0,代表游标没有打开;当其值为-1时,表示游标为动态的;当其值为-m(m为正整数)时,游标采用异步方式填充,m为当前键集中已经填充的行数
- 当其值为m(m为正整数)时,游标已被完全填充,m是游标中的数据行数
示例: 定义游标输出其值
use test1;
go
declare cursor01 cursor
local
scroll
scroll_locks
type_warning
for select 学号,出生日期,专业 from xsb
for update
open cursor01
select 'rows'=@@CURSOR_ROWS
读取数据
游标打开后就可以用fetch
语句从中读取数据了
语法格式:
fetch
[
[next|prior|first|absolute{n|@nvar}|relative{n|@nvar}]
from
]
{{[global]游标名}|@游标变量名}
[into @变量名[,...]]
语句 | 含义 |
---|---|
游标名 | 要从中提取的游标名 |
@游标变量名 | 引用要进行提取操作的已打开的游标 |
next“”prior“”first“”absolute“”relative | 指定读取数据的位置,并使其置为当前行。next为默认的游标提取选项。first和last不能在只进游标中进行;nexr读取下一行;prior读取当前行的前一行;first读取游标的第一行;last读取游标中的最后一行; |
into | 将读取的游标数据存放到指定的变量中 |
global | 全局游标 |
示例:
-- 使用数据库
use test1;
go
-- 声明游标
declare cur02 cursor
global
scroll
dynamic
scroll_locks
type_warning
for select * from xsb
for update
-- 打开游标
open cur02
-- 声明存放游标的变量
declare @Id int,@name char(10),@sex bit,@date date,@major char(12),@score int,@text varchar(50)
-- 遍历游标
fetch first from cur02 into @id,@name,@sex,@date,@major,@score,@text
while @@FETCH_STATUS=0 -- @@FETCH_STATUS 为0 代表游标语句执行成功 为-1或-2代表执行失败 其中-1是遇到了小错误 -2是遇到了大错误
begin
fetch next from cur02 into @id,@name,@sex,@date,@major,@score,@text
print 'id:'+convert(varchar(50),@id)+'name:'+@name+'sex:'+convert(char(1),@sex)+'date:'+convert(varchar,@date)+'major:'+@major
end
-- 关闭游标
close cur02
-- 释放游标
deallocate cur02
关闭游标
语法格式如下:
close 游标名
释放游标
语法格式如下:
deallocate 游标名