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

原创 2007年05月12日 12:30:00

表现:

将数据库兼容级别从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  信息可以观察得到. 它产生了IS S

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

 

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

表现:将数据库兼容级别从80 改到90 后,下面的游标循环不出数据,但单独SELECT有结果DECLARE MyCursor CURSOR LOCAL READ_ONLYFOR SELECT    C...
  • alex197963
  • alex197963
  • 2007年05月13日 11:58
  • 650

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

表现:将数据库兼容级别从80 改到90 后, 下面的游标循环不出数据, 但单独SELECT 有结果DECLARE MyCursor CURSOR LOCAL READ_ONLYFOR  SELECT ...
  • techcrunch
  • techcrunch
  • 2008年01月03日 14:32
  • 198

VS2008 问题汇总

1.中文乱码问题: 在资源视图中,右击对话框IDD,选择属性,将语言更改为Chinese (Simplified, PRC)即可。   或者在新建工程时,资源语言选择中文: 2.编译报错,需要编...
  • armfpga123
  • armfpga123
  • 2016年08月29日 11:23
  • 345

事务隔离性

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 事务隔离性: Read Uncommitted(读取...
  • l4432321
  • l4432321
  • 2018年01月10日 16:41
  • 19

Hibernate中list和Iterate区别

oracle数据库表dept3 create table dept3 as select * from dept; alter table dept3 modify(deptno number p...
  • yiyiquegai
  • yiyiquegai
  • 2012年08月10日 11:32
  • 674

bug产生的原因

功能与数据库耦合: 单纯查询: #由于数据非常复杂,sql错误 #由于数据归类非常复杂,研发对待查询的数据理解错误,导致错误的sql语句 #由于研发采用了某些查询策略,导致了数据查询的延迟 ...
  • cidiwuyin
  • cidiwuyin
  • 2017年02月15日 17:47
  • 499

hibernate的N+1条SQL查询问题--Iterate和list

hibernate使用session.createQuery(hql)查询数据的时候,有两种查询方式 1、session.createQuery(hql).list() 2、session.cre...
  • u011936251
  • u011936251
  • 2017年08月18日 07:44
  • 126

我的解决org.apache.commons.lang.xwork.StringUtils异常的方法

网上解决org.apache.commons.lang.xwork.StringUtils异常的方法都弱爆了,看我怎么解决它!                                   ...
  • localhost01
  • localhost01
  • 2016年06月01日 15:41
  • 545

多线程(一):多线程问题产生原因

从 Java 内存模型分析多线程以及多线程产生的原因。
  • u014077165
  • u014077165
  • 2015年03月10日 21:25
  • 1565

过拟合产生的原因和预防

1,什么是过拟合(overfitting) 简单的说就是这样一种学习现象:Ein 很小,Eout 却很大。 而Ein 和 Eout 都很大的情况叫做 underfitting。 这是机器学习中两...
  • findsd1989
  • findsd1989
  • 2015年05月21日 17:16
  • 1682
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:游标类型产生的数据检索问题
举报原因:
原因补充:

(最多只允许输入30个字)