数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

深入讲解游标类型为什么会产生数据检索[2]


发布日期:2021年04月21日
 
深入讲解游标类型为什么会产生数据检索[2]

在定义此类游标的情况下 S锁是必须下的 NOLOCK提示并不会起作用此现象通过查询游标OPEN时的sp_lock信息就可以观察得到它产生了IS和S锁

而NOLOCK 提示是否起作用 会影响的执行的结果(执行计划一样 但在取数据的时候 却会有所差异)

对于下面这句 有NOLOCK 和无NOLOCK 时 它取的数据是不一样的 因为它只取了TOP 而且没有ORDER BY 来保证取数的顺序 所以取数据顺序的细致差异 就导致了最终结果的不同 而最终结果的不同 导致了整个游标取出来的数据不同

SELECT TOP()

KeyID

FROM tbmaster WITH(NOLOCK)

WHERE Date >= //

AND Date < //)

在游标定义SELECT 语句中 当NOLOCK 有效时 是可以取到数据的 但NOLOCK 无效(DYNAMIC 游标导致)时 查询结果是无数据的

所以最终看到的结果是: 游标循环不出来数据 但只做查询却有数据

如果把游标定义中的查询语句的NOLOCK 去掉做查询 也会没有数据(与DYNAMIC 游标结果一致)

故这个问题严格来说不应该是兼容级别的问题 级别下 还是有可能发生 只是机率更小 或者是内部执行原理不太一样 导致没有这种情况出来而已

由于没有ORDER BY来保证顺序 而有无NOLOCK的数据可能不会一样 所以下都可能出现问题 只是会显得比较突出 或者仅仅时正好被发现了

解决方法如下:

首先需要把游标定义改成下面的这样不会导致NOLOCK 失效 而且速度比原来的定义方式快得多 如果游标一定要与原始表的数据变化关联起来 建议用KEYSET 或者是去掉NOLOCK 提示(因为没有意义) 假如对取的数据有要求 我们还应当考虑加ORDER BY来保证取数顺序

DECLARE MyCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC

FOR

[] []

               

上一篇:数据库基础:初学者需要掌握的数据库设计词汇对照表[1]

下一篇:深入讲解游标类型为什么会产生数据检索[1]