SQL server游标
有 select 语句返回的完整行集称为结果集,应用程序特别是嵌套到 T-SQL 语句中的应用程序,并不总能将整个结果集作为一个单元来有效处理,这里应用程序需要一种机制以便每次处理一行或一部分行,游标就是提供这种机制的对结果集的一种扩展。
游标的基本概念
由 select 语句返回的完整行称为结果集,在使用 select 语句进行查询时可以得到这个结果集,但有时用户需要对结果集中的某行或部分行进行单独的处理,这在select 的结果集中无法实现,游标(cursor)就是提供这种机制的对结果集的一种扩展,SQL server 通过游标提供了对一个结果集进行逐行处理的能力。
游标包括两部分内容:
- 游标结果集:定义游标的 select 语句返回的结果集的集合。
- 游标当前行指针:指向该结果集中某一行的指针。
游标的优点:
- 允许定位在结果集的特定行。
- 从结果集的当前位置检索一行或一部分行
- 支持对结果集中当前位置的行进行数据修改
- 为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
- 提供脚别、存储过程和触发器中用于访问结果集中数据的 T-SQL 语句
- 使用游标可以在检查数据的同时对数据进行处理
游标的基本操作
游标的基本操作包括声明游标、打开游标、提取游标、关闭游标和删除游标。
1.声明游标
声明游标使用 declare cursor 语句
语法格式:
declare cursor_name [insensitive][scroll] cursor
for select_statement
[for { read only | update [of column_name [,...n]]}]
说明:
- cursor_name:游标名,它是与某个查询结果集相关联的符号名。
- insensitive:指定系统将创建供所定义的游标使用的数据的临时副本,对游标的所有请求都从 temp、db 的该临时表中得到应答,因此在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。如果省略 insensitive,则任何用户对基表提交的删除和更新都反映在后面的提取中。
- scroll:说明所声明的游标可以前滚、后滚,可使用所有的提取选项(first、last、prior、next、relative、absolute)。如果省略scroll,则只能使用next 提取选项。
- select_statement:select 语句,偶该查询产生与所声明的游标相关联的结果集。在该 select 语句中不能出现 compute、compute by、into 或 for browse 关键字。
- read only:说明所声明的游标为只读的。
2.打开游标
游标在声明而且被打开以后位于第一行,打开游标使用 open 语句。
语法格式:
open {{[global] cursor_name} | cursor_variable_name}
其中,cursor_name 是要打开的游标名,sursor_variable_name 是游标变量名,该名称引用一个游标。global 说明打开的是全局游标,否则打开局部游标
3. 提取数据
游标在打开后使用 fetch 语句提取数据。
语法格式:
fetch [ [next | priop | first | last | absolute { n | @nvar} | relative {n | @nvar}] from]
{ { [global] cursor_name} | @cursor_variable_name}
[into @variable_name [,...n] ]
说明:
- cursor_name:要从中提取数据的游标名,@cursor_variable_name 为游标变量名,引用要进行提取操作的已打开的游标。
- next | priop | first | last:用于说明读取数据的位置。next 说明读取当前行的下一行,并且使用前置为当前行。如果 fetch next 是对游标的第一次提取操作,则读取的是结果集的第一行,next 为默认的游标提取选项。priop 说明读取当前行的前一行,并且使其置为当前行。如果fetch priop 是对游标的第一次提取操作,则物质返回且游标置于第一行之前。first 读取游标中的第一行并将其作为当前行。last 读取游标中的最后一行并将其作为当前行。
- absolute{n | @nvar} 和 ralative{n | @nvar}:给出读取数据的位置与游标头或当前位置的关系,其中 n 必须为整型常量,变量 @nvar 必须为 smallint、tinyint 或 int 类型。
- into:将读取的游标数据存放到指定的变量中。
- global:全局游标。
再提起数据时用到的游标函数有@@fetch_status。
@@fetch_status 函数用于返回上一条游标 fetch 语句的状态。
语法格式:
fetch_status
( { 'local' , 'cursor_name'} 指明数据源为本地游标
| { 'global' , 'cursor_name'} 指明数据源为全局游标
|{ 'variable' , cursor_variable} 指明数据源为游标变量
)
其中,常量字符串 local、global 用于指定游标类型,local 表示为本地游标,global 表示全局游标。参数 cursor_name 用于指定游标名。常量字符串 variable 用于说明其后的游标变量为一个本地变量,参数 cursor_name 为本地游标变量名。@@fetch_status 函数的返回值如下图所示。
4.关闭游标
游标使用完毕后要及时关闭,关闭游标使用 close 语句,
语法格式:
close { { [global] cursor_name } | @cursor_variable_name }
5. 删除游标
在游标关闭后如果不再需要游标,应该释放其定义所占用的系统空间,即删除游标。删除游标使用 deallocate 语句。
语法格式:
deallocate { { [global] cursor_name } | @cursor_variable_name }
6.举例
declare @sno char(10),@Sname char(20)
declare cur_student cursor for select Sno,Sname from Student --创建游标
open cur_student --打开游标
fetch cur_student into @sno,@sname
while @@fetch_status=0
begin
print @sno + ':' + @sname
fetch cur_student into @sno,@sname --获取数据
end
close cur_student --关闭游标
deallocate cur_student --删除游标
运行结果:
游标的使用
使用游标的基本过程如下:
- 声明 T-SQL 变量
- 使用 declare cursor 语句声明游标。
- 使用 open、 语句打开游标
- 使用 fetch 提取数据
- 使用 deallocate 语句删除游标