SQLServer帮助中心(SQL游标)

游标的类型

createStatement参数解释

SQL Server Mobile 支持下列游标类型:

基表

静态

只进

只进/只读

键集驱动

 

基表游标

基表游标是可用的最低级别的游标。这些游标直接在存储引擎上工作,是所有支持的游标类型中速度最快的游标。基表游标可以最低开销向前或向后滚动,并且可以更新。

您还可以直接在索引上打开游标。此类游标支持索引,以便对表中的行进行排序、允许查找特定值以及基于索引中的值的范围对行进行限制。

基表游标具有动态成员身份。这意味着,在同一个表上打开的两个游标可以立即看见对数据的插入、删除和更改(假定它们两个都在同一事务作用范围内)。由于可以更新基表游标,因此客户端可以使用此类游标来更改基本数据。

基表游标无法表示查询结果。查询结果(例如 SELECT * FROM tablename)无法通过基表游标返回。而是使用支持的查询结果游标返回结果。

下面的示例说明如何使用 ADO .NET 获取基表游标:

//Base Table Cursor

cmd.CommandText = "tablename";

cmd.CommandType = CommandType.TableDirect;

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);

下面的示例说明如何使用 ADO .NET 获取索引游标:

cmd.CommandText = "tablename";

cmd.IndexName = "indexname";

cmd.CommandType = CommandType.TableDirect;

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);

静态游标

静态游标(在以前的 SQL Server Mobile 版本中称为可滚动查询游标)可以创建和存储结果集的完整副本。当用户显式请求检索的长整型值数据时例外。只有在需要时才填充此结果集。这与 SQL Server 不同,后者在创建游标时就会填充结果集。静态游标支持向后滚动和向前滚动,但不支持更新。静态游标无法看见外部对不敏感的数据所做的更改。在游标的生存周期内将缓存查询结果。尽管静态游标比只进游标功能更强,但静态游标速度较慢,并且会使用更多的内存。建议只有在需要滚动并且键集游标不合适时再考虑使用静态游标。

下面的示例说明如何使用 ADO.NET 获取静态游标:

cmd.CommandText = "Select * from tablename";

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Insensitive);

只进游标

只进游标是可更新的速度最快的游标,但不支持滚动。它只支持从游标头至游标尾顺序提取行。在提取行之前,无法从数据库中检索这些行。从游标提取行时,由当前用户创建或由其他用户提交并会影响结果集中的行的所有 INSERT、UPDATE 和 DELETE 语句的效果均可见。由于游标无法向后滚动,因此在行被提取之后,将无法通过使用游标看见在数据库中对行所做的更改。

只进游标和只进/只读游标是基于查询的速度最快的游标。它们应当用在优先考虑速度和内存占用量的方案中。

下面的示例说明如何使用 ADO .NET 获取只进游标:

cmd.CommandText = "Select * from tablename";

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable);

只进/只读游标

只进/只读游标(在以前的 SQL Server Mobile 版本中称为只进游标)是最快的游标,但无法进行更新。

下面的示例说明如何使用 ADO.NET 获取只进/只读游标:

cmd.CommandText = "Select * from tablename";

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.None);

注意   不能在只返回只读列的查询上创建只读游标,因为内部的所有 SQL Server Mobile 游标都是可更新的。SQL Server Mobile 无法更新在 SqlCeResultSet 中返回的只读列。因此,它将失败,并返回错误“由于不存在可更新列,因此无法生成用于查询的可更新游标”。


键集驱动游标

SQL Server Mobile 中的键集驱动游标是可以进行更新的可滚动游标。键集驱动游标由一组称为键集的物理标识符来控制。键集基于在打开游标时对 SELECT 语句验证合格的所有行。在打开游标时将在临时表中生成键集。使用键集驱动游标,将在执行查询时确定成员身份。

SQL Server Mobile 中的键集驱动游标与 SQL Server 中的键集驱动游标有细微的差别。在 SQL Server 中,键集驱动游标使用一组唯一标识符作为键集中的键。在 SQL Server Mobile 中,键是表示值在表中的逻辑存储位置的书签。它们不是唯一标识符。

尽管对许多更改敏感,但键集驱动游标不如其他游标敏感。例如,尽管在游标内的插入将在结束时可以看见,但无法看见在游标外的插入。在这种情况下,建议您关闭并重新打开游标,或使用一个只进游标。

由于 SQL Server Mobile 使用书签来定义键集,因此通过使用游标,对键集中所包括行的数据值所做的所有更改都是可见的。对于在游标内所做的更改和在游标外所做的更改,情况都是这样的。

无论是在游标内还是在游标外,在键集游标中所做的任何删除操作都将导致在试图提取行时报告该行已被删除。

下面的示例说明如何使用 ADO .NET 获取键集驱动游标:

cmd.CommandText = "Select * from tablename";

SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);

使用联接
如果用来打开键集驱动游标的查询包含联接的列,则这些列不可更新。用户可以向这些列中插入新值,但不支持更新。

如果键集被用来填充用户可更新的控件(如 DataGrid 对象),则用户可能会试图更新控件中的值,此时更新将失败。如果要开发的应用程序将使用 DataGrid 来显示联接的列数据,请确保在 DataGrid 中将联接的列设置为只读。

选择游标类型  

游标类型的选择取决于下列几个变量:

结果集的大小。

可能需要的数据百分比。

打开游标的性能。

游标操作需求,例如滚动或定位的更新。

其他用户所做数据修改的可见性级别。

选择游标类型的规则

选择游标类型时要遵循的规则包括:

打开基表游标和只进游标要快于打开静态游标或键集驱动游标。打开静态游标和键集驱动游标时必须生成内部临时工作表,而对于基表游标和只进游标则没有这个要求。

静态游标和键集驱动游标会增加临时数据库的使用量。静态服务器游标在临时数据库中生成整个游标。键集驱动游标在临时数据库中生成键集。

如果按照原样检索基表(不进行任何映射或选择),则推荐使用基表游标,因为它的额外开销最小。

静态游标消耗的资源最多,因为他们会复制数据。

 游标和锁定  

在 Microsoft SQL Server 2005 Mobile Edition (SQL Server Mobile) 中,游标定义中的 SELECT 语句受限于应用到任何其他 SELECT 语句中的相同事务锁定规则。任何 SELECT 语句(包括游标定义中的 SELECT 语句)所获取的事务锁都由以下因素控制:

为连接所设置的事务隔离级别

在 FROM 子句中指定的任何锁定提示。

只对于基表或索引游标而言,事务隔离级别可能会影响到所获取的锁。

重要事项: 
对于 READ COMMITTED 的默认隔离级别,SQL Server Mobile 不会在定位或读取数据时获取锁。READ COMMITTED 中的游标要求 Sch-S 锁以保护游标打开时架构的稳定性。如果数据被更改,则采用排他锁。
 


锁一直持有到同时用于游标和独立 SELECT 语句的当前事务结束为止。

获取锁

尽管对于所获取的事务锁类型而言,游标遵循的规则与独立 SELECT 语句的规则相同,但获取锁的时间却不相同。独立 SELECT 或游标生成的锁始终是在要求行时获取的。对于独立 SELECT,在执行该语句时,会检索所有行。游标会根据游标类型在不同时间检索行:

静态游标会在打开游标时检索整个结果集。这会在打开时锁定结果集的每行。

键集驱动的游标会在打开游标时检索结果集的每行中的键。这会在打开时锁定结果集的每行。

在提取只进游标之前,它们不会检索行。在定位行之前,不会在行上获取锁。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值