关系数据库中的操作会对整个行集起作用。由 SELECT 语句返回的行集包括满足该语句的 WHERE 子句中条件的所有行。这种由语句返回的完整行集称为结果集。应用程序,特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。这些应用程序需要一种机制以便每次处理一行或一部分行。游标就是提供这种机制的对结果集的一种扩展。
游标通过以下方式来扩展结果处理:
- 允许定位在结果集的特定行。
- 从结果集的当前位置检索一行或一部分行。
- 支持对结果集中当前位置的行进行数据修改。
- 为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
- 提供脚本、存储过程和触发器中用于访问结果集中的数据的 Transact-SQL 语句。
Microsoft SQL Server 2005 支持两种请求游标的方法:
- Transact-SQL
Transact-SQL 语言支持使用根据 SQL-92 游标语法制定的游标的语法。 - 数据库应用程序编程接口(API)游标函数
SQL Server 支持以下数据库 API 的游标功能:
- ADO(Microsoft ActiveX 数据对象)
- OLE DB
- ODBC(开放式数据库连接)
应用程序不能混合使用这两种请求游标的方法。已经使用 API 指定游标行为的应用程序不能再执行 Transact-SQL DECLARE CURSOR 语句请求一个 Transact-SQL 游标。应用程序只有在将所有的 API 游标特性设置回默认值后,才可以执行 DECLARE CURSOR。
如果既未请求 Transact-SQL 游标也未请求 API 游标,则默认情况下 SQL Server 将向应用程序返回一个完整的结果集,这个结果集称为默认结果集。
Transact-SQL 游标和 API 游标有不同的语法,但下列一般进程将用于所有 SQL Server 游标:
- 将游标与 Transact-SQL 语句的结果集相关联,并且定义该游标的特性,例如是否能够更新游标中的行。
- 执行 Transact-SQL 语句以填充游标。
- 从游标中检索您想要查看的行。从游标中检索一行或一部分行的操作称为提取。执行一系列提取操作以便向前或向后检索行的操作称为滚动。
- 根据需要,对游标中当前位置的行执行修改操作(更新或删除)。
- 关闭游标。
==================================================================================
提交要执行的请求后,Microsoft SQL Server 2005 将按以下方式将结果集发送回客户端:
- SQL Server 从客户端接收包含要执行的 Transact-SQL 语句或一批 Transact-SQL 语句的网络数据包。
- SQL Server 编译并执行该语句或该批语句。
- SQL Server 开始将结果集或者来自批处理或存储过程的多个结果集的行放在网络数据包中,然后发送给客户端。SQL Server 在每个数据包中放置尽可能多的结果集行。
- 包含结果集行的数据包被缓存在客户端的网络缓冲区中。当客户端应用程序提取这些行时,ODBC 驱动程序或 OLE DB 访问接口从网络缓冲区中提取这些行,然后将数据传输给客户端应用程序。客户端每次向前检索一行结果。
这种返回结果的模式称为默认结果集。
SQL Server 2005 提供了在一个连接下拥有多个活动结果集的功能,这通常称为 MARS。必须为每个连接显式启用此功能。此功能仅在 SQL Native Client ODBC 驱动程序、SQL Native Client OLEDB 访问接口和 .NET Framework 2.0 SqlClient 托管访问接口中提供。
使用连接字符串特性或会话属性为某个特定的会话启用 MARS:
- 对于 ODBC,应将 SQL_COPT_SS_MARS_ENABLED 设置为 SQL_MARS_ENABLED_YES
- 对于 OLEDB,应将 SSPROP_INIT_MARSCONNECTION 设置为 VARIANT_TRUE
- 对于 SqlClient 托管访问接口,必须将连接字符串特性 MultipleActiveResultSets 设置为 True。
MARS 只在连接了 SQL Server 2005 的客户端提供程序中可用。MARS 在早期版本的客户端提供程序或 SQL Server 的任意组合中均不可用。
在早期版本的 SQL Server 或未启用 MARS 的会话中,在应用程序处理 SQL Server 返回的所有行或者向 SQL Server 发送取消其余结果的请求之前,客户端无法通过某个特定的连接发送任何其他请求。必须先处理完所有结果才能通过该连接进行任何更新。
注意: |
---|
“消防队游标”是默认结果集以前的叫法,现已不再使用。
|
默认结果集是在没有请求游标时 SQL Server 所使用的结果集处理类型。满足下列条件时会出现这种情况:
- 应用程序没有使用 DECLARE CURSOR 语句请求 Transact-SQL 服务器游标,而是直接执行了 Transact-SQL 语句,例如 SELECT。
- 如果应用程序使用 ADO、OLE DB 和 ODBC,它将令所有 API 游标特性都使用默认设置,这样就不会请求任何 API 游标。这一默认特性集的目的是请求行集大小为 1 的只进只读游标。
- 由于这种处理方式是在所有游标特性均设置为默认值以及 SQL Server 或数据库 API 实际并未涉及游标处理的情况下使用,因此被称为默认结果集。
默认结果集不会以一大块的形式提供给应用程序。结果集被缓存在客户端的网络缓冲区内。应用程序每次从结果集中提取一行。每次提取时,OLE DB 访问接口或 ODBC 驱动程序将数据从网络缓冲区的下一行转移到应用程序的变量内。OLE DB、ODBC 和 ADO 应用程序用来检索行的 API 函数与从游标中提取行所用的 API 函数相同。SqlClient 托管访问接口使用 SqlDataReader 类来显示默认结果集。当 MultipleActiveResultSets 设置为 True 时,允许在某个给定的时间打开多个 SqlDataReader。
默认结果集是将结果传输给客户端的最有效的方法。从客户机发送给服务器的唯一数据包就是包含要执行语句的原始数据包。当结果被发送回客户端时,SQL Server 将尽可能多的结果集行放到每个数据包中,以最大程度地减少发送给客户端的数据包数量。
使用默认结果集时,支持所有的 Transact-SQL 语句。使用默认结果集时,还可以执行包含多个语句(这些语句返回结果集)的批处理或存储过程。
默认结果集只能用于将结果集发送回客户端应用程序。默认结果集中的数据对批处理、存储过程或触发器中的任何其他 Transact-SQL 语句或变量都不可用。例如,以存储过程或触发器中的以下语句为例:
SELECT ProductID FROM AdventureWorks.Production.Product;
该语句生成一个默认结果集,其中包含 AdventureWorks 数据库中所有产品的 ID,该结果集被 SQL Server 直接发送给客户端。存储过程或触发器中的所有其他 Transact-SQL 语句或变量都不能引用此产品 ID 列表。若要使此结果集中的数据能够被其他 Transact-SQL 语句使用,必须将数据放在 Transact-SQL 服务器游标中:
DECLARE abc CURSOR FOR SELECT ProductID FROM AdventureWorks.Production.Product;
==================================================================================
Microsoft SQL Server 2005 支持三种游标实现:
-
Transact-SQL 游标
-
基于 DECLARE CURSOR 语法,主要用于 Transact-SQL 脚本、存储过程和触发器。Transact-SQL 游标在服务器上实现并由从客户端发送到服务器的 Transact-SQL 语句管理。它们还可能包含在批处理、存储过程或触发器中。
-
应用程序编程接口 (API) 服务器游标
-
支持 OLE DB 和 ODBC 中的 API 游标函数。API 服务器游标在服务器上实现。每次客户端应用程序调用 API 游标函数时,SQL Native Client OLE DB 访问接口或 ODBC 驱动程序将把请求传输到服务器,以便对 API 服务器游标进行操作。
-
客户端游标
-
由 SQL Native Client ODBC 驱动程序和实现 ADO API 的 DLL 在内部实现。客户端游标通过在客户端高速缓存所有结果集行来实现。每次客户端应用程序调用 API 游标函数时,SQL Native Client ODBC 驱动程序或 ADO DLL 就对客户端上高速缓存的结果集行执行游标操作。
由于 Transact-SQL 游标和 API 服务器游标都在服务器上实现,所以它们统称为服务器游标。
不要混合使用这些不同类型的游标。如果从一个应用程序中执行 DECLARE CURSOR 和 OPEN 语句,请首先将 API 游标属性设置为默认值。否则就会要求 SQL Server 将 API 游标映射到 Transact-SQL 游标。例如,不要将 ODBC 属性设置为需要将由键集驱动的游标映射到结果集,然后使用该语句句柄执行 DECLARE CURSOR 和 OPEN 以调用 INSENSITIVE 游标。
服务器游标的一个潜在缺点是它们目前并不支持所有的 Transact-SQL 语句。服务器游标不支持生成多个结果集的 Transact-SQL 语句,因此,当应用程序执行包含多个 SELECT 语句的存储过程或批处理时,不能使用服务器游标。服务器游标也不支持包含 COMPUTE、COMPUTE BY、FOR BROWSE 或 INTO 关键字的 SQL 语句。
使用游标不如使用默认结果集的效率高。在默认结果集中,从客户端发送到服务器的唯一数据包是包含待执行语句的数据包。而在使用服务器游标时,每个 FETCH 语句都必须从客户端发送到服务器,然后在服务器上分析并编译为执行计划。
如果某个 Transact-SQL 语句将返回一个相对较小的结果集,可以高速缓存在客户端应用程序可用的内存中,而且您知道必须在执行该语句之前检索整个结果集,那么请使用默认结果集。只有在需要进行游标操作以支持应用程序的功能,或者可能只需检索结果集的一部分时,才应使用服务器游标。
用服务器游标代替客户端游标有以下几个优点:
- 性能
在访问游标中的部分数据时(这在许多浏览应用程序中很常见),使用服务器游标能够提供最佳的性能,因为只通过网络发送提取的数据。客户端游标则将整个结果集高速缓存在客户端。 - 其他游标类型
如果 SQL Native Client ODBC 驱动程序只使用客户端游标,它可能只支持只进游标和静态游标。通过使用 API 服务器游标,该驱动程序也可以支持由键集驱动的游标和动态游标。SQL Server 还支持只有通过服务器游标才能获得的所有游标并发属性。客户端游标仅限于它们所支持的功能。 - 更精确的定位更新
服务器游标直接支持定位操作,例如 ODBC 的 SQLSetPos 函数,或带有 WHERE CURRENT OF 子句的 UPDATE 和 DELETE 语句。另一方面,通过生成 Transact-SQL 搜索的 UPDATE 语句,客户端游标可以模拟定位游标更新,如果有多个行满足 UPDATE 语句的 WHERE 子句的条件,这将导致意外更新。 - 内存使用
在使用服务器游标时,客户端无需高速缓存大量数据或维护游标位置的信息,因为这些工作由服务器完成。 - 多个活动语句
使用服务器游标时,结果不会存留在游标操作之间的连接上。这就允许同时拥有多个基于游标的活动语句。
除了静态游标或不敏感游标外,所有服务器游标的操作都取决于基础表的架构。声明游标后对这些表的架构进行任何更改都将导致该游标的后续操作发生错误。
==================================================================================
在 OLE DB、ODBC 和 ADO 规范中,游标在 Transact-SQL 语句返回的任何结果集上是隐式打开的。在执行 Transact-SQL 语句之前,应该先设置定义游标特征的特性或属性。然后可以调用 API 函数,以便一次提取一行或多行。API 游标特性或属性的默认设置与 Microsoft SQL Server 默认结果集具有相同的特征。当游标特性或属性设置为默认值时,SQL Native Client ODBC 驱动程序和 SQL Native Client OLE DB 访问接口均实现默认结果集。这种情况下不使用游标。仅当游标特性或属性的设置改为非默认值时,驱动程序和访问接口才实现游标。
OLE DB、ODBC、和 ADO 在表示结果集和游标的这种组合时使用不同的术语:
- OLE DB 使用术语“行集”来表示结果集以及与其关联游标行为的组合。
- ODBC 有时混用“结果集”和“游标”这两个术语,因为它考虑到每个结果集上都自动映射了一个游标。ODBC 中的行集特指一次提取所返回的行数。
- ADO 使用术语“记录集”,与 OLE DB 使用术语“行集”的方式一样。
Microsoft SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序默认使用一个 API 服务器游标来实现请求的任何游标函数。通过加载 ODBC 游标库,ODBC 客户端应用程序可以用客户端游标代替服务器游标。OLE DB 自己并不实现客户端游标,但 ADO API 则实现。
下表概述了基于当前的 API 游标设置和正在执行的 Transact-SQL 语句实现的游标或结果集类型。标有“请不要混用游标类型”的单元表示正在同时请求 Transact-SQL 服务器游标和 API 游标。这可能会导致无法预期的行为,因此不应当这样做。
API 游标设置 | 执行的 Transact-SQL 语句:DECLARE CURSOR | 执行的 Transact-SQL 语句:SELECT、批过程 |
---|---|---|
OLE DB/ODBC/ADO:默认游标设置 | Transact-SQL 游标 | 默认结果集 |
OLE DB/ODBC/ADO:非默认游标设置;无客户端游标库 | 请不要混用游标类型。 | API 服务器游标 不支持批处理和过程 |
OLE DB/ODBC/ADO:非默认游标设置;已加载客户端游标库 | 请不要混用游标类型。 | 默认结果集被缓存到客户端游标中 |
================================================================================
Transact-SQL 游标主要用于存储过程、触发器和 Transact-SQL 脚本中,它们使结果集的内容可用于其他 Transact-SQL 语句。
在存储过程或触发器中使用 Transact-SQL 游标的典型过程为:
- 声明 Transact-SQL 变量包含游标返回的数据。为每个结果集列声明一个变量。声明足够大的变量来保存列返回的值,并声明变量的类型为可从列数据类型隐式转换得到的数据类型。
- 使用 DECLARE CURSOR 语句将 Transact-SQL 游标与 SELECT 语句相关联。另外,DECLARE CURSOR 语句还定义游标的特性,例如游标名称以及游标是只读还是只进。
- 使用 OPEN 语句执行 SELECT 语句并填充游标。
- 使用 FETCH INTO 语句提取单个行,并将每列中的数据移至指定的变量中。然后,其他 Transact-SQL 语句可以引用那些变量来访问提取的数据值。Transact-SQL 游标不支持提取行块。
- 使用 CLOSE 语句结束游标的使用。关闭游标可以释放某些资源,例如游标结果集及其对当前行的锁定,但如果重新发出一个 OPEN 语句,则该游标结构仍可用于处理。由于游标仍然存在,此时还不能重新使用该游标的名称。DEALLOCATE 语句则完全释放分配给游标的资源,包括游标名称。释放游标后,必须使用 DECLARE 语句来重新生成游标。
可以使用 sp_cursor_list 系统存储过程来获得对当前连接可见的游标列表,使用sp_describe_cursor、sp_describe_cursor_columns 和 sp_describe_cursor_tables 来确定游标的特性。
打开游标后,@@CURSOR_ROWS 函数或者由 sp_cursor_list 或 sp_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 2005 也支持 cursor 数据类型的变量。可以通过两种方法将游标与 cursor 变量相关联:
/* Use DECLARE @local_variable, DECLARE CURSOR and SET. */ DECLARE @MyVariable CURSOR DECLARE MyCursor CURSOR FOR SELECT LastName FROM AdventureWorks.Person.Contact SET @MyVariable = MyCursor GO /* Use DECLARE @local_variable and SET */ DECLARE @MyVariable CURSOR SET @MyVariable = CURSOR SCROLL KEYSET FOR SELECT LastName FROM AdventureWorks.Person.Contact; DEALLOCATE MyCursor;
游标与 cursor 变量相关联之后,在 Transact-SQL 游标语句中就可以使用 cursor 变量而非使用游标名称。存储过程输出参数也可指定为 cursor 数据类型,并与游标相关联。这就允许存储过程有节制地公开其局部游标。
Transact-SQL 游标名称和变量只能由 Transact-SQL 语句引用,而不能由 OLE DB、ODBC 和 ADO 的 API 函数引用。例如,如果使用 DECLARE CURSOR 和 OPEN 定义并打开 Transact-SQL 游标,就无法使用 ODBC SQLFetch 函数或 SQLFetchScroll 函数来从 Transact-SQL 游标中提取行。需要游标处理且使用这些 API 的应用程序应该使用在数据库 API 中生成的游标支持而非使用 Transact-SQL 游标。
可以通过使用 FETCH 并将 FETCH 返回的每列绑定到程序变量,在应用程序中使用 Transact-SQL 游标。但是,Transact-SQL FETCH 不支持批处理,因此,这是将数据返回给应用程序的效率最低的方法。每提取一行均需往返服务器一次。使用在数据库 API(支持多行提取)中生成的游标功能更为有效。
包含在存储过程和触发器中的 Transact-SQL 游标效率极高。这是因为所有操作都编译到服务器上的一个执行计划内,不存在与行提取关联的网络流量。
在 SQL Server 2005 中,发出打开游标时其中值有更改的 FETCH 语句时,会发生错误。发生此类错误的原因可能是下列影响计划的选项或索引视图和计算列所需的选项。若要避免此类错误,请勿在打开游标时更改 SET 选项。
影响计划的选项 | ARITHABORT NUMERIC_ROUNDABORT FORCEPLAN QUOTED_IDENTIFIER ANSI_NULL_DFLT_ON ANSI_NULL_DFLT_OFF ANSI_WARNINGS ANSI_PADDING ANSI_NULLS CONCAT_NULL_YIELDS_NULL DATEFIRST DATEFORMAT LANGUAGE TEXTSIZE |
索引视图和计算列 | ANSI_NULLS ANSI_PADDING ANSI_WARNINGS ARITHABORT(兼容级别为 80 或更低) CONCAT_NULL_YIELDS_NULL QUOTED_IDENTIFIER NUMERIC_ROUNDABORT |
在 SQL Server 2000 中,尽管对其他选项进行更改会导致发生错误,但对 ANSI_NULLS 和 QUOTED_IDENTIFIER 进行更改不会导致发生错误。
================================================================================
OLE DB、ODBC 和 ADO API 支持将游标映射到已执行 SQL 语句的结果集。Microsoft SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序通过使用 API 服务器游标来实现这些操作。API 服务器游标在服务器上实现,并由 API 游标函数进行管理。当应用程序调用 API 游标函数时,游标操作由 OLE DB 访问接口或 ODBC 驱动程序传送给服务器。
当在 OLE DB、ODBC 和 ADO 中使用 API 服务器游标时,使用 API 函数和方法实现如下功能:
- 打开一个连接。
- 设置定义游标特征的特性或属性,API 自动将游标映射到每个结果集。
- 执行一个或多个 Transact-SQL 语句。
- 使用 API 函数或方法提取结果集中的行。
当 API 游标特性或属性设为默认值时,SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序将使用默认结果集。虽然从技术上说 API 需要游标,但默认游标特征与默认结果集的行为是匹配的。因此,OLE DB 访问接口和 ODBC 驱动程序使用默认结果集实现默认游标选项,因为这是从服务器中检索行的最有效的方法。使用默认结果集时,应用程序可以执行任何 Transact-SQL 语句或批处理,但它只允许一个连接中有一个未完成的语句。这意味着应用程序必须处理或取消由一个语句返回的所有结果集,然后才能执行连接中的下一个语句。
当 API 游标特性或属性没有设为默认值,SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序将使用 API 服务器游标代替默认结果集。每次对提取行的 API 函数的调用都会产生到服务器的一次往返,以从 API 服务器游标中提取行。
使用 API 服务器游标时,应用程序不能执行下列语句:
- 服务器游标中 SQL Server 不支持的 Transact-SQL 语句。
- 返回多个结果集的批处理或存储过程。
- 包含 COMPUTE、COMPUTE BY、FOR BROWSE 或 INTO 子句的 SELECT 语句。
- 引用远程存储过程的 EXECUTE 语句。
SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序使用下面这些特殊的系统存储过程向服务器发出游标操作信号:
- sp_cursoropen 定义与游标和游标选项相关联的 SQL 语句,然后填充游标。
- sp_cursorfetch 从游标中提取一行或一个行块。
- sp_cursorclose 关闭并释放游标。
- sp_cursoroption 用于设置各种游标选项。
- sp_cursor 用于请求定位更新。
- sp_cursorprepare 将与游标有关的 Transact-SQL 语句或批处理编译成执行计划,但并不创建游标。
- sp_cursorexecute 从 sp_cursorprepare 创建的执行计划中创建并填充游标。
- sp_cursorunprepare 丢弃 sp_cursorprepare 生成的执行计划。
- sp_cursorprepexec 为提交的与游标相关联的 Transact-SQL 语句或批处理编译计划,创建并填充游标。sp_cursorprepexec 结合了 sp_cursorprepare 和 sp_cursorexecute 的行为。
这些系统存储过程将出现在使用 API 服务器游标的 ADO、OLE DB 和 ODBC 应用程序的 SQL Server Profiler 跟踪中。它们仅供 SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 启动程序内部使用。应用程序可通过数据库 API 的游标功能来使用这些过程的完整功能。不支持在应用程序中直接指定过程。
当 SQL Server 执行某个连接中的一个语句时,只有先处理完或取消第一个语句的所有结果才能执行连接中的其他语句。此规则在使用 API 服务器游标时仍然适用,但从应用程序的角度看,好像 SQL Server 已经开始支持一个连接中存在多个活动语句。这是因为完整的结果集存储在服务器游标中,并且只有传送给 SQL Server 的语句才执行 sp_cursor 系统存储过程。SQL Server 将执行存储过程,并且只要客户端检索到结果集,它就能执行任何其他语句。OLE DB 访问接口和 ODBC 驱动程序则在将控制返回给应用程序之前始终检索来自 sp_cursor 存储过程的所有结果集。这使应用程序可以插空在多个活动服务器游标中进行提取操作。
下表说明了应用程序如何利用两个语句句柄在一个连接上同时处理两个游标。
语句句柄 1 | 语句句柄 2 |
---|---|
设置游标特性,以便使用 API 服务器游标。 |
|
SQLExecDirect 一个 SQL 语句。ODBC 驱动程序调用 sp_cursoropen,然后检索该过程所返回的结果集。 |
|
| 设置游标特性,以便使用 API 服务器游标。 |
| SQLExecDirect 一个 SQL 语句。ODBC 驱动程序调用 sp_cursoropen,然后检索该过程所返回的结果集。 |
SQLFetchScroll 检索第一个行块。驱动程序调用 sp_cursorfetch,然后检索该过程所返回的结果集。 |
|
| SQLFetchScroll 检索第一个行块。驱动程序调用 sp_cursorfetch,然后检索该过程所返回的结果集。 |
SQLFetchScroll 检索另一个行块。驱动程序调用 sp_cursorfetch,然后检索该过程所返回的结果集。 |
|
| SQLFetchScroll 检索另一个行块。驱动程序调用 sp_cursorfetch,然后检索该过程所返回的结果集。 |
调用 SQLFreeStmt 或 SQLCloseCursor。驱动程序调用 sp_cursorclose。 |
|
| 调用 SQLFreeStmt 或 SQLCloseCursor。驱动程序调用 sp_cursorclose。 |
由于调用 sp_cursor 存储过程之后连接中不再有未完成的结果,因此可以在一个连接中并发执行多个 Transact-SQL 语句,只要它们都是使用 API 服务器游标执行的。
下面是有关如何在 API 中使用 API 服务器游标的摘要:
- OLE DB
- 打开会话对象,然后打开命令对象并指定命令文本。
- 设置行集属性(例如 DBPROP_OTHERINSERT、DBPROP_OTHERUPDATEDELETE、DBPROP_OWNINSERT、DBPROP_OWNUDPATEDELETE 等)以控制游标行为。
- 执行命令对象。
- 使用下列方法提取结果集中的行,如 IRowset::GetNextRows、IRowsetLocate::GetRowsAt、IRowsetLocate::GetRowsAtBookmark 和 IRowsetScroll::GetRowsAtRatio。
- ODBC
- 打开一个连接,然后调用 SQLAllocHandle 以分配语句句柄。
- 调用 SQLSetStmtAttr 以设置 SQL_ATTR_CURSOR_TYPE、SQL_ATTR_CONCURRENCY 和 SQL_ATTR_ROW_ARRAY_SIZE 特性。也可以通过设置 SQL_ATTR_CURSOR_SCROLLABLE 和 SQL_ATTR_CURSOR_SENSITIVITY 特性来指定游标行为。
- 使用 SQLExecDirect 或 SQLPrepare 和 SQLExecute 执行 Transact-SQL 语句。
- 使用 SQLFetch 或 SQLFetchScroll 提取行或行块。
- ADO
- 定义 Connection 对象和 Recordset 对象,然后对 Connection 对象执行 Open 方法。
- 指定 CursorType 和/或 LockType 参数,对 Recordset 对象执行 Open 方法。
- 使用 Move、MoveFirst、MoveLast、MoveNext 和 MovePrevious 记录集方法提取行。
在 SQL Server 2005 中,如果发出提取语句,并且对下列影响计划的任何选项或索引视图或计算列需要的选项进行了更改,游标将使用打开时生效的选项值的快照。这些值将用于所有后续的提取操作,在当前上下文中所做的更改将被忽略。
影响计划的选项 | ARITHABORT NUMERIC_ROUNDABORT FORCEPLAN QUOTED_IDENTIFIER ANSI_NULL_DFLT_ON ANSI_NULL_DFLT_OFF ANSI_WARNINGS ANSI_PADDING ANSI_NULLS CONCAT_NULL_YIELDS_NULL DATEFIRST DATEFORMAT LANGUAGE TEXTSIZE |
索引视图和计算列 | ANSI_NULLS ANSI_PADDING ANSI_WARNINGS ARITHABORT(兼容级别为 80 或更低)CONCAT_NULL_YIELDS_NULL QUOTED_IDENTIFIER NUMERIC_ROUNDABORT |
=================================================================================
ODBC 支持客户端游标,即在客户端实现的游标。在客户端游标中,将使用默认结果集把整个结果集高速缓存在客户端上,所有的游标操作都针对此客户端高速缓存来执行。将不使用 Microsoft SQL Server 2005 的任何服务器游标功能。客户端游标仅支持只进和静态游标,不支持由键集驱动的游标和动态游标。
ODBC 将实现使用 ODBC 游标库的客户端游标。这是为了用于仅支持游标特性默认设置的 ODBC 驱动程序。由于 SQL Native Client ODBC 驱动程序完全支持通过服务器游标进行的游标操作,因此应限制客户端游标的使用。
客户端游标应只用于缓解由于服务器游标不支持所有的 Transact-SQL 语句或批处理而带来的限制。如果需要在不能用服务器游标执行的 Transact-SQL 语句或批处理上使用静态的滚动游标,则可以考虑使用客户端游标。