`

游标类型产生的数据检索问题

 
阅读更多
表现:
将数据库兼容级别从80 改到90 ,下面的游标循环不出数据,但单独SELECT有结果
DECLARE MyCursor CURSOR LOCAL READ_ONLY
FOR
SELECT
Col1
FROM tbname WITH(NOLOCK)
WHERE Name LIKE 'SNET%'
AND B_Key IN(
SELECT TOP(100)
KeyID
FROM tbmaster WITH(NOLOCK)
WHERE Date >= '01/01/2007'
AND Date < '02/01/2007')
OPEN MyCursor
FETCH NEXT FROM MYCURSOR
WHILE (@@FETCH_STATUS=0)
BEGIN
FETCH NEXT FROM MYCURSOR
END
CLOSE MyCursor
DEALLOCATE MyCursor
分析:
导致出现这个情况的原因是游标类型的问题.
按照上述定义,游标类型是: DYNAMIC
定义这种游标的情况下, S 锁是必须下的, NOLOCK 提示不会起作用,这个通过查询游标OPEN时的sp_lock信息可以观察得到.它产生了ISS
NOLOCK提示是否起作用,会影响的执行的结果(执行计划一样,但在取数据的时候,会有所差异)
对于下面这句,NOLOCK和无NOLOCK,它取的数据是不一样的,因为它只取了TOP 100, 而且没有ORDER BY 来保证取数的顺序,所以取数据顺序的细致差异,就导致了最终结果的不同.而最终结果的不同,导致了整个游标取出来的数据不同.
SELECT TOP(100)
KeyID
FROM tbmaster WITH(NOLOCK)
WHERE Date >= '01/01/2007'
AND Date < '02/01/2007')
在游标定义SELECT语句中,NOLOCK有效时,是可以取到数据的,NOLOCK无效(DYNAMIC游标导致),查询结果是无数据的
所以最终看到的结果是:游标循环不出来数据,但只做查询却有数据.
如果把游标定义中的查询语句的NOLOCK去掉做查询,也会没有数据(DYNAMIC游标结果一致)
故这个问题严格来说不应该是兼容级别的问题,80 级别下,还是有可能发生,只是机率更小,或者是内部执行原理不太一样,导致没有这种情况出来而已
因为没有ORDER BY 保证顺序,而有无NOLOCK的数据可能不会一样,所以理论上80 90 下都可能出现问题,只是90 比较突出,或者正好被发现了而已
解决的办法:
把游标定义改成下面的,这样不会导致NOLOCK失效,而且速度比原来的定义方式快得多.如果游标一定要与原始表的数据变化关联起来,建议用KEYSET,或者是去掉NOLOCK提示(因为没有意义),如果对取的数据是有要求的,则还应该考虑加ORDER BY 保证取数顺序
DECLARE MyCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC
FOR
分享到:
评论

相关推荐

    Java数据库编程宝典2

    15.2.2 从数据库中检索的数据作为XML文档 15.2.3 使用XSL样式表转换XML 15.2.4 在JSP页面中使用XSL转换 15.3 使用具有XSL样式表的可更新ResultSet 15.4 小结 第16章 使用JDBC驱动的JavaMail API 16.1 使用...

    Java数据库编程宝典4

    15.2.2 从数据库中检索的数据作为XML文档 15.2.3 使用XSL样式表转换XML 15.2.4 在JSP页面中使用XSL转换 15.3 使用具有XSL样式表的可更新ResultSet 15.4 小结 第16章 使用JDBC驱动的JavaMail API 16.1 使用...

    Java数据库编程宝典1

    15.2.2 从数据库中检索的数据作为XML文档 15.2.3 使用XSL样式表转换XML 15.2.4 在JSP页面中使用XSL转换 15.3 使用具有XSL样式表的可更新ResultSet 15.4 小结 第16章 使用JDBC驱动的JavaMail API 16.1 使用...

    Java数据库编程宝典3

    15.2.2 从数据库中检索的数据作为XML文档 15.2.3 使用XSL样式表转换XML 15.2.4 在JSP页面中使用XSL转换 15.3 使用具有XSL样式表的可更新ResultSet 15.4 小结 第16章 使用JDBC驱动的JavaMail API 16.1 使用...

    oracle数据库经典题目

    游标的作用是将数据库的中数据检索出来后缓存,可以被PL/SQL程序一行一行的读取并处理。支持一条、多条、零条记录的处理。 游标的基本操作步骤为: (1)声明游标,使用查询来定义游标的列和行 (2)打开游标,使用PL/...

    SQL语法大全

    Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下: ----------------------------------------------------...

    java面试题

    答:索引可以提高对数据库中数据的检索,缺点是减慢了数据录入速度,同时也增加了数据库的尺寸大小。 什么是事务?什么是事锁? 答:事务就是被绑定在一起,作为一个逻辑单元执行的SQL语句。如果任何一个操作失败,...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。 ...

    传智播客扫地僧视频讲义源码

    13_新增数据类型bool类型 14_中午课程回顾 15_c++中的三目运算符_传智扫地僧 16_const的基础和const符号表机制探究_传智扫地僧 17_const和#define的对比_传智扫地僧 18_引用的基础知识(定义和函数参数) 19_复杂数据...

    jdbc基础和参考

    对持久对象的更动,会对数据库中的数据产生影响。(自动脏检查机制) Detached(托管状态): 1.和Session失去关联 2.数据库中有对应记录存在 3.对托管对象的更动,在托管期间不会影响数据库,但是将托管状态重新和...

    黄淮学院2010学年第二学期SQL server期末考试

    游标是一种处理数据的方法,它可对结果集进行_________。 A、逐行处理 B、修改处理 C、分类处理 D、服务器处理 SQL Server 2005 采用的身份验证模式有_________。 A、仅Windows身份验证模式 B、仅SQL Server身份...

    Oracle9i的init.ora参数中文说明

    说明: 与 NLS_TIME_FORMAT 相似, 只不过它设置的是 TIMESTAMP 数据类型的默认值, 该数据类型既存储YEAR, MONTH 和 DAY 这几个日期值, 也存储 HOUR, MINUTE 和 SECOND 这几个时间值。 语法: TIMESTAMP '1997-01-31 ...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    (2)跨域数据交互问题。不同的Webview之间无法共享数据。(3)页面自适应问题。页面难以兼容适应不同分辨率的设备和浏览器。 本文研究并设计了基于Android+HTML5的在线认证检测系统,主要工作包括以下四个方面: ...

Global site tag (gtag.js) - Google Analytics