陋室铭
永远也不要停下学习的脚步(大道至简至易)

SQL-Server支持三种游标类:
客户端游标
API服务器游标
T-SQL游标

T-SQL游标和其它类型游标之间的主要区别在于它们的用途不一样。
在存储过程、批处理、函数或触发器中使用的T-SQL用于对每一行游标进行重复定制处理。
其它种类的游标用于从客户端应用程序访问数据库信息。

在MSSQL的联机帮助中搜索:”Transact-SQL 游标“可以得到详细的信息。
MSDN 中文帮助地址为:http://msdn2.microsoft.com/zh-cn/library/ms190028.aspx

Transact-SQL 游标

Transact-SQL 游标主要用在存储过程、触发器和 Transact-SQL 脚本中,它们使结果集的内容对其它 Transact-SQL 语句同样可用。

在存储过程或触发器中使用 Transact-SQL 游标的典型进程为:

  1. 声明 Transact-SQL 变量包含游标返回的数据。为每一结果集列声明一个变量。声明足够大的变量以保存由列返回的值,并声明可从列数据类型以隐性方式转换得到的数据类型。

  2. 使用 DECLARE CURSOR 语句把 Transact-SQL 游标与一个 SELECT 语句相关联。DECLARE CURSOR 语句同时定义游标的特征,比如游标名称以及游标是否为只读或只进特性。

  3. 使用 OPEN 语句执行 SELECT 语句并生成游标。

  4. 使用 FETCH INTO 语句提取单个行,并把每列中的数据转移到指定的变量中。然后,其它 Transact-SQL 语句可以引用这些变量来访问已提取的数据值。Transact-SQL 不支持提取行块。

  5. 结束游标时,使用 CLOSE 语句。关闭游标可以释放某些资源,比如游标结果集和对当前行的锁定,但是如果重新发出一个 OPEN 语句,则该游标结构仍可用于处理。由于游标仍然存在,此时还不能重新使用游标的名称。DEALLOCATE 语句则完全释放分配给游标的资源,包括游标名称。在游标被释放后,必须使用 DECLARE 语句来重新生成游标。
监视 Transact-SQL 游标的活动

可以使用 sp_cursor_list 系统存储过程来获得对当前连接可见的游标列表,使用sp_describe_cursorsp_describe_cursor_columnssp_describe_cursor_tables 来确定游标的特征。

在游标打开后,@@CURSOR_ROWS 函数或由 sp_cursor_listsp_describe_cursor 返回的 cursor_rows 列会指出游标中的行数。

在每个 FETCH 语句执行之后,@@FETCH_STATUS 更新以反映最后一次提取的状态。也可以从由 sp_describe_cursor 返回的 fetch_status 列中获取该状态信息。@@FETCH_STATUS 报告游标中的状态,比如超出第一行和最后一行的提取。@@FETCH_STATUS 对于连接来说是全局性的,并在连接游标打开时由每次提取进行重置。如果必须在以后了解状态,就需要在连接中执行另外一个语句之前,把 @@FETCH_STATUS 保存在一个用户变量中。即使下一语句不是 FETCH,也可能是 INSERT、UPDATE 或 DELETE 这些语句,它们能够激发包含可重置 @@FETCH_STATUS 的 FETCH 语句的触发器。sp_describe_cursor 返回的 fetch_status 列对于指定的游标来说是确定的,不受那些引用其它游标的 FETCH 语句的影响,但 sp_describe_cursor 会受引用相同游标的 FETCH 语句的影响,因此使用时必须注意。

完成 FETCH 后,游标将定位在已提取的行上。被提取的行称为当前行。如果游标没有声明为只读游标,就可以执行带有 WHERE CURRENT OF cursor_name 子句的 UPDATE 或 DELETE 语句来修改当前行。

由 DECLARE CURSOR 语句赋给 Transact-SQL 游标的名称可以是全局或局部的。全局游标的名称可由任何位于同一连接上的批处理、存储过程或触发器引用。局部游标名称不能在声明游标的批处理、存储过程或触发器之外被引用。触发器和存储过程中的局部游标因而可以避免来自存储过程或触发器外部的无意引用。

使用游标变量

Microsoft® SQL Server™ 2000 也支持 cursor 数据类型的变量。游标可以有两种方法与一个 cursor 变量相关联:

/* Use DECLARE @local_variable, DECLARE CURSOR and SET. */
DECLARE @MyVariable CURSOR

DECLARE MyCursor CURSOR FOR
SELECT LastName FROM Northwind.dbo.Employees

SET @MyVariable = MyCursor

/* Use DECLARE @local_variable and SET */
DECLARE @MyVariable CURSOR

SET @MyVariable = CURSOR SCROLL KEYSET FOR
SELECT LastName FROM Northwind.dbo.Employees

当游标与 cursor 变量相关联之后,在 Transact-SQL 游标语句中就可以使用 cursor 变量代替游标名称。存储过程输出参数也可指派为 cursor 数据类型,并与一个游标相关联。这就允许存储过程有节制地展示其局部游标。

引用 Transact-SQL 游标

Transact-SQL 游标名称和变量只能由 Transact-SQL 语句引用,而不能由 OLE DB、ODBC、ADO 和 DB-Library 的 API 函数引用。例如,如果要使用 DECLARE CURSOR 和 OPEN 语句生成一个 Transact-SQL 游标,就无法使用 SQLFetchSQLFetchScroll 函数来从 Transact-SQL 游标中提取行。需要游标处理而又使用这些 API 的应用程序应该使用数据库 API 中内建的游标支持代替 Transact-SQL 游标。

通过使用 FETCH 并绑定由 FETCH 返回给程序变量的每一列,可以在应用程序中使用 Transact-SQL 游标。Transact-SQL FETCH 不支持批处理,因此,这是将数据返回给应用程序的效率最低的方法。每提取一行均需往返服务器一次。使用内建在数据库 API 中的游标功能更为有效,可进行多行提取。

当包含在存储过程和触发器中时,Transact-SQL 游标极其有效。这是因为所有操作都编译到服务器上的一个执行计划内,不存在与行提取有关的网络流量。

posted on 2006-10-10 14:05  宏宇  阅读(445)  评论(1编辑  收藏  举报