Transact-SQL中游标名的作用域
2024-07-21 02:06:41
供稿:网友
microsoft sql server 2000支持关键字global和local用于declare cursor 语句中游标名作用域的定义。global指定游标名在一个连接中是全局的。local指定游标名在存储过程,触发器,包含declare cursor的批处理语句中是局部的。
microsoft sql server 7.0版本以前,在一个连接中,游标名都是全局的。你必须先执行一个用于创建游标的存储过程,然后再执行另外一个从该游标中读取记录的存储过程。如:
use pubs
go
create procedure opencrsr as
declare samplecrsr cursor for
select au_lname
from authors
where au_lname like 's%'
open samplecrsr
go
create procedure readcrsr as
fetch next from samplecrsr
while (@@fetch_status <> -1)
begin
fetch next from samplecrsr
end
go
exec opencrsr /* 声明并打开游标samplecrsr. */
go
exec readcrsr /* 从游标samplecrsr中读取记录. */
go
close samplecrsr
go
deallocate samplecrsr
go
局部游标在存储过程和触发器中对游标起着重要的保护作用。全局游标能在定义它们的存储过程或触发器外被访问。因此,它们可能在不经意的时候,在存储过程和触发器外被改变。局部游标显得更安全,因为它们不会在存储过程和触发器外被改变,除非特地的通过输出游标参数被传递给调用者。
因为全局游标可以在存储过程和触发器以外被引用,所以它们可能对其他语句有不可预期的影响。例如:一个存储过程创建一个全局游标xyz,过程运行结束后游标xyz仍然处于打开状态,如果程序其他部分又想声明一个全局游标并命名为xyz,这时,就会发生一个重复定义的错误。
全局和局部游标具有不同的命名空间,所以,在同一时间可以出现两个具有同样名字的全局和局部游标。transact-sql语法支持游标参数,同样也支持使用global标识游标的作用域。如果一个游标名同时表示全局游标和局部游标,在没有指定为global时,此游标名将引用局部游标。
数据库选项default to local cursor控制由未指定global和local选项的declare cursor语句创建的游标的默认作用域。如果default to local cursor 选项为真,则为局部游标,反之为全局。sql server 2000中,default to local cursors 选项默认为false,用于保持与先前版本一致。
声明并且打开局部游标的存储过程,可以将这些游标传出给调用它的存储过程,触发器和批处理语句。这可以通过一个定义为输出参数的cursor varying 数据类型实现。当存储过程执行结束时,游标必须打开,用以通过输出参数返回。我们可以用一个定义为cursor类型的局部变量引用它。
use pubs
go
/* create a procedure with a cursor output parameter. */
create procedure opencrsr @outcrsr cursor varying output as
set @outcrsr = cursor for
select au_lname
from authors
where au_lname like 's%'
open @outcrsr
go
/* 声明局部游标. */
declare @crsrvar cursor
/* 将先前的游标赋给局部变量. */
exec opencrsr @outcrsr = @crsrvar output
/* 利用@crsrvar去读取记录. */
fetch next from @crsrvar
while (@@fetch_status <> -1)
begin
fetch next from @crsrvar
end
close @crsrvar
deallocate @crsrvar
go
数据库api并不支持输出游标参数的存储过程。一个包含输出游标参数的存储过程不能直接被数据库api执行。这些存储过程之可以被其他的存储过程,触发器,transact-sql 批处理,脚本调用执行。
全局游标在没有被显式释放或连接关闭前一直有效。局部游标默认将在存储过程,触发器,批处理结束时释放,除非它被作为输出参数输出。那个局部游标也将在引用它的存储工程结束时被释放。