关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » SQL Server »SQL Server游标的正确使用与注意事项(1)

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

    2010-07-26 10:59:00 出处:ITJS
    分享

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

    形式1(ANSI 92)

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

    形式2

    DECLARE cursor_name CURSOR  [LOCAL | GLOBAL]  [FORWARD_ONLY | SCROLL]  [STATIC | KEYSET | DYNAMIC]  [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]  FOR select_statement  [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命令的语法如下:

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

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

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

    FIRST是结果集的第一行。

    LAST是结果集的最后一行。

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

    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游标处理的循环。

    例如:

    DECLARE @iname char(20), @fname char(20)  OPEN author_cur  FETCH FIRST FROM author_cur INTO @iname, @fname  WHILE @@fetch_status = 0 BEGIN  IF @fname = ‘Albert’  PRINT “Found Albert Ringer”  ELSE  Print “Other Ringer”  FETCH NEXT FROM author_cur INTO @iname, @fname  END 

    iv. 关闭游标

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

    CLOSE [GLOBAL] cursor_name | cursor_variable_name 

    v. 释放游标

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

    DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name 

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

    USE master  GO  CREATE PROCEDURE sp_BuildIndexes  AS  DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)  DECLARE table_cur CURSOR FOR  SELECT name FROM sysobjects WHERE type=’u’  OPEN table_cur  FETCH NEXT FROM table_cur INTO @TableName  WHILE @@fetch_status = 0 BEGIN  IF @@fetch_status = -2  CONTINUE  SELECT @msg = “Building indexes for table”+@TableName+”…”  PRINT @msg  SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”  EXEC (@cmd)  PRINT “ “  FETCH NEXT FROM table_cur INTO @TableName  END  DEALLOCATE table_cur  GO 

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

    USE pubs  GO  EXEC ap_BuildIndexes 

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

    使用临时表

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

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

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

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

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

    形式1(ANSI 92)

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

    形式2

    DECLARE cursor_name CURSOR  [LOCAL | GLOBAL]  [FORWARD_ONLY | SCROLL]  [STATIC | KEYSET | DYNAMIC]  [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]  FOR select_statement  [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命令的语法如下:

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

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

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

    FIRST是结果集的第一行。

    LAST是结果集的最后一行。

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

    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游标处理的循环。

    例如:

    DECLARE @iname char(20), @fname char(20)  OPEN author_cur  FETCH FIRST FROM author_cur INTO @iname, @fname  WHILE @@fetch_status = 0 BEGIN  IF @fname = ‘Albert’  PRINT “Found Albert Ringer”  ELSE  Print “Other Ringer”  FETCH NEXT FROM author_cur INTO @iname, @fname  END 

    iv. 关闭游标

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

    CLOSE [GLOBAL] cursor_name | cursor_variable_name 

    v. 释放游标

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

    DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name 

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

    USE master  GO  CREATE PROCEDURE sp_BuildIndexes  AS  DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)  DECLARE table_cur CURSOR FOR  SELECT name FROM sysobjects WHERE type=’u’  OPEN table_cur  FETCH NEXT FROM table_cur INTO @TableName  WHILE @@fetch_status = 0 BEGIN  IF @@fetch_status = -2  CONTINUE  SELECT @msg = “Building indexes for table”+@TableName+”…”  PRINT @msg  SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”  EXEC (@cmd)  PRINT “ “  FETCH NEXT FROM table_cur INTO @TableName  END  DEALLOCATE table_cur  GO 

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

    USE pubs  GO  EXEC ap_BuildIndexes 

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

    使用临时表

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

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

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

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

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    帝国CMS7.5编辑器上传图片取消宽高的三种方法

    帝国cms如何自动生成缩略图的实现方法

    Windows 12即将到来,将彻底改变人机交互

    帝国CMS 7.5忘记登陆账号密码怎么办?可以phpmyadmin中重置管理员密码

    帝国CMS 7.5 后台编辑器换行,修改回车键br换行为p标签

    Windows 11 版本与 Windows 10比较,新功能一览

    Windows 11激活产品密钥收集及专业版激活方法

    如何从 Windows 11 中完全删除/卸载 OneNote?无解!

    抖音安全与信任开放日:揭秘推荐算法,告别单一标签依赖

    ultraedit编辑器打开文件时,总是提示是否转换为DOS格式,如何关闭?

    IT头条

    华为Pura80系列新机预热,余承东力赞其复杂光线下的视频拍摄实力

    01:28

    阿里千问3开源首战告捷:全球下载破千万,国产AI模型崛起新高度!

    01:22

    DeepSeek R1小版本试升级:网友实测编程能力已达到国际一线水平

    23:15

    NVIDIA 与 Dell 合作,大规模交付 Blackwell AI 系统

    20:52

    Cerebras 以最快的 Llama 4 Maverick 性能引领 LLM 推理竞赛

    20:51

    技术热点

    PHP中的随机性——你觉得自己幸运吗?

    搞定Ubuntu Linux下WPA无线上网

    Java使用内存映射实现大文件的上传

    MySQL安全性指南

    MySQL两项性能的基本测试浅谈

    教您使用UniqueIdentifier选取SQL Server主键

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。