SQL Server游标的正确使用与注意事项

此文章主要向大家讲述的是学习SQL Server游标的正确使用,在这一步中,需要指定SQL Server数据库的游标属性与根据要求,而产生的结果集。一共有两种方法可以指定一个游标。以下就是对这两种形式的描述。

形式1(ANSI 92)

 

  1. DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR  
  2. FOR select_statement  
  3. [FOR {READ ONLY | UPDATE ][OF column_list]}] 

形式2

 

  1. DECLARE cursor_name CURSOR  
  2. [LOCAL | GLOBAL]  
  3. [FORWARD_ONLY | SCROLL]  
  4. [STATIC | KEYSET | DYNAMIC]  
  5. [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]  
  6. FOR select_statement  
  7. [FOR {READ ONLY | UPDATE ][OF column_list]}] 

INSENSITIVE关键字指明要为检索到的结果集建立一个临时拷贝,以后的数据从这个临时拷贝中获取。如果在后来SQL Server游标处理的过程中,原有基表中数据发生了改变,那么它们对于该游标而言是不可见的。这种不敏感的游标不允许数据更改。

SCROLL关键字指明游标可以在任意方向上滚动。所有的fetch选项(first、last、next、relative、absolute)都可以在游标中使用。如果忽略该选项,则游标只能向前滚动(next)。

Select_statement指明SQL语句建立的结果集。Transact SQL语句COMPUTE、COMPUTE BY、FOR BROWSE和INTO在游标声明的选择语句中不允许使用。

READ ONLY指明在游标结果集中不允许进行数据修改。

UPDATE关键字指明游标的结果集可以修改。

OF column_list指明结果集中可以进行修改的列。缺省情况下(使用UPDATE关键字),所有的列都可进行修改。

LOCAL关键字指明游标是局部的,它只能在它所声明的过程中使用。

GLOBAL关键字使得游标对于整个连接全局可见。全局的游标在连接激活的任何时候都是可用的。只有当连接结束时,游标才不再可用。

FORWARD_ONLY指明游标只能向前滚动。

 

STATIC的游标与INSENSITIVE的游标是相同的。

KEYSET指明选取的行的顺序。SQL Server将从结果集中创建一个临时关键字集。如果对数据库的非关键字列进行了修改,则它们对游标是可见的。因为是固定的关键字集合,所以对关键字列进行修改或新插入列是不可见的。

DYNAMIC指明游标将反映所有对结果集的修改。

SCROLL_LOCK是为了保证游标操作的成功,而对修改或删除加锁。

OPTIMISTIC指明哪些通过SQL Server游标进行的修改或者删除将不会成功。

注意:

如果在SELECT语句中使用了DISTINCT、UNION、GROUP BY语句,且在选择中包含了聚合表达式,则游标自动为INSENSITIVE的游标。

如果基表没有唯一的索引,则游标创建成INSENSITIVE的游标。

如果SELECT语句包含了ORDER BY,而被ORDER BY的列并非唯一的行标识,则DYNAMIC游标将转换成KEYSET游标。如果KEYSET游标不能打开,则将转换成INSENSITIVE游标。使用SQL ANSI-92语法定义的游标同样如此,只是没有INSENSITIVE关键字而已。

ii. 打开游标

打开游标就是创建结果集。SQL Server游标通过DECLARE语句定义,但其实际的执行是通过OPEN语句。语法如下:

OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}

GLOBAL指明一个全局游标。

 

Cursor_name是被打开的游标的名称。

Cursor_variable_name是所引用游标的变量名。该变量应该为游标类型。

在游标被打开之后,系统变量@@cursor_rows可以用来检测结果集的行数。@@cursor_rows为负数时,表示游标正在被异步迁移,其绝对值(如果@@cursor_rows为-5,则绝对值为5)为当前结果集的行数。异步游标使用户在游标被完全迁移时仍然能够访问游标的结果。

iii. 从游标中取值

在从游标中取值的过程中,可以在结果集中的每一行上来回移动和处理。如果游标定义成了可滚动的(在声明时使用SCROLL关键字),则任何时候都可取出结果集中的任意行。对于非滚动的游标,只能对当前行的下一行实施取操作。结果集可以取到局部变量中。Fetch命令的语法如下:

  1. FETCH [NEXT | PRIOR| FIRST | LAST | ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar}]  
  2. FROM [GLOBAL] cursor_name} | cursor_variable_name}  
  3. [INTO @variable_name ][,……n]] 

NEXT指明从当前行的下一行取值。

 

PRIOR指明从当前行的前一行取值。

FIRST是结果集的第一行。

LAST是结果集的最后一行。

ABSOLUTE n表示结果集中的第n行,该行数同样可以通过一个局部变量传播。行号从0开始,所以n为0时不能得到任何行。#p#

RELATIVE n表示要取出的行在当前行的前n行或后n行的位置上。如果该值为正数,则要取出的行在当前行前n行的位置上,如果该值为负数,则返回当前行的后n行。

INTO @cursor_variable_name表示游标列值存储的地方的变量列表。该列表中的变量数应该与DECLARE语句中选择语句所使用的变量数相同。变量的数据类型也应该与被选择列的数据类型相同。直到下一次使用FETCH语句之前,变量中的值都会一直保持。

每一次FETCH的执行都存储在系统变量@@fetch_status中。如果FETCH成功,则@@fetch_status被设置成0。@@fetch_status为-1表示已经到达了结果集的一部分(例如,在游标被打开之后,基表中的行被删除)。@@fetch_status可以用来构造SQL Server游标处理的循环。

例如:

  1. DECLARE @iname char(20), @fname char(20)  
  2. OPEN author_cur  
  3. FETCH FIRST FROM author_cur INTO @iname, @fname  
  4. WHILE @@fetch_status = 0 
  5. BEGIN  
  6. IF @fname = ‘Albert’  
  7. PRINT “Found Albert Ringer”  
  8. ELSE  
  9. Print “Other Ringer”  
  10. FETCH NEXT FROM author_cur INTO @iname, @fname  
  11. END 

iv. 关闭游标

 

CLOSE语句用来关闭游标并释放结果集。游标关闭之后,不能再执行FETCH操作。如果还需要使用FETCH语句,则要重新打开游标。语法如下:

  1. CLOSE [GLOBAL] cursor_name | cursor_variable_name 

v. 释放游标

 

游标使用不再需要之后,要释放游标。DEALLOCATE语句释放数据结构和游标所加的锁。语法如下:

  1. DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name 

下面给出SQL Server游标的一个完整的例子:

 

  1. USE master  
  2. GO  
  3. CREATE PROCEDURE sp_BuildIndexes  
  4. AS  
  5. DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)  
  6. DECLARE table_cur CURSOR FOR  
  7. SELECT name FROM sysobjects WHERE type=’u’  
  8. OPEN table_cur  
  9. FETCH NEXT FROM table_cur INTO @TableName  
  10. WHILE @@fetch_status = 0 
  11. BEGIN  
  12. IF @@fetch_status = -2  
  13. CONTINUE  
  14. SELECT @msg = “Building indexes for table”+@TableName+”…”  
  15. PRINT @msg  
  16. SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”  
  17. EXEC (@cmd)  
  18. PRINT “ “  
  19. FETCH NEXT FROM table_cur INTO @TableName  
  20. END  
  21. DEALLOCATE table_cur  
  22. GO 

下面的脚本将为PUBS数据库执行sp_BuildIndexes

 

  1. USE pubs  
  2. GO  
  3. EXEC ap_BuildIndexes 

注意:上面也是创建用户定义的系统存储过程的示例。

使用临时表

临时表是在TempDB中创建的表。临时表的名称都以“#”开头。临时表的范围为创建临时表的连接。因为,临时表不能在两个连接之间共享,一旦连接关闭,临时表就会被丢弃。如果临时表被创建于存储过程之中,则临时表的范围在存储过程之中,或者被该存储过程调用的任何存储过程之中。

如果需要在连接之间共享临时表,则需要使用全局的临时表。全局的临时表以“##”符号开头,它将一直存在于数据库中,直到SQL Server重新启动。一旦这类临时表创建之后,所有的用户都可以访问到。在临时表上不能明确地指明权限。

临时表提供了存储中间结果的能力。有时候,临时表还能通过将一个复杂的查询分解成两个查询而获得性能的改善。这可以通过首先将第一个查询的结果存在临时表中,然后在第二个查询中使用临时表来实现。当一个大表中的某个子集在一个在座过程中使用多次时,建议使用临时表。

在这种情况下,在临时表中保持数据的子集,以在随后的连接中使用,这样能大大改善性能。还可以在临时表中创建索引。以上的相关内容就是对学习SQL Server游标的使用的介绍,望你能有所收获。

【编辑推荐】

  1. SQL Server复制和其相关的工作原理
  2. SQL Server存储图像数据大阅兵
  3. MS SQL Server 未公开的加密函数有哪些?
  4. 快速对SQL Server锁机制进行掌握的窍门
  5. SQL Server删除重复数据的2个实用方案#p##p#

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/271167.html<

(0)
管理的头像管理
上一篇2025-05-08 04:00
下一篇 2025-05-08 04:02

相关推荐

  • 站群服务器到底是什么意思,怎么选择比较好

    站群服务器就是一台拥有多个独立IP地址、专门用于托管和管理多个网站的高性能服务器,其核心价值在于通过独立IP降低网站间的关联风险,并提升搜索引擎优化效果,站群服务器的工作原理与适用场景站群服务器本质上是将一台物理服务器通过虚拟化或直接配置的方式,分配给多个独立IP地址,每个IP对应一个独立的网站,这些网站共享服……

    2026-07-27
    0
  • 高防服务器误封正常流量如何调整,怎么解决?

    高防服务器误封正常流量,核心调整思路是从“一刀切”转向“精细化”——通过分析业务特征,调整防护阈值、配置白名单和启用智能学习模式,让防护系统学会区分真假流量,为什么会误封正常流量误封主要源于防护策略的通用化,高防服务器通常默认启用严格防护规则,当流量特征与攻击特征库部分匹配时,就会被拦截,据行业安全白皮书指出……

    2026-07-27
    0
  • 高防服务器的防御原理是什么,如何选择高防服务器?

    高防服务器的防御原理,简单说就是通过流量清洗、防火墙规则和黑洞路由等机制,在攻击流量到达业务服务器之前将其过滤或阻断,从而保障正常访问,流量清洗机制是核心防线高防服务器对抗DDoS攻击,靠的不是单一技术,而是一套组合动作,最常见的攻击类型是流量型攻击,比如UDP洪水、SYN洪水、ICMP放大等,核心思路是耗尽带……

    2026-07-26
    0
  • BGP线路到底是什么意思呢,有什么优势?

    BGP线路是一种通过边界网关协议实现多运营商网络互联的接入方式,能自动选择最优路径,极大提升跨网访问速度和稳定性,是解决国内南北网络瓶颈的核心方案,什么是BGP线路BGP,全称Border Gateway Protocol,边界网关协议,是互联网核心路由协议之一,它负责在自治系统之间交换网络可达性信息,BGP线……

    2026-07-26
    0
  • 增值电信业务经营许可证对IDC有多重要,如何办理?

    增值电信业务经营许可证是IDC服务商合法运营的核心凭证,它直接决定了机房能否接入骨干网、客户能否放心托管业务,以及服务商自身能否长期稳定发展,许可证是IDC进入市场的硬门槛互联网数据中心业务属于增值电信业务中的B1类,依据工信部《电信业务经营许可管理办法》,任何从事服务器托管、虚拟主机、云服务等业务的企业,必须……

    2026-07-26
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注