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

运维 数据库运维
数据检索(data retrieval)是将经过选择、整理和评价(鉴定)的数据存入某种载体中,并根据用户需要从某种数据集合中检索出能回答问题的准确数据过程或技术。那么游标类型为什么会产生数据检索呢?

导读:游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。本文将为大家深入讲解游标类型为什么会产生数据检索的问题。
游标类型产生的数据检索问题:

  现象:

  在将数据库兼容的级别从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 ***00)
  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 时, 它取的数据是不一样的, 因为它只取了***00, 而且没有ORDER BY 来保证取数的顺序, 所以取数据顺序的细致差异, 就导致了最终结果的不同. 而最终结果的不同, 导致了整个游标取出来的数据不同。

  SELECT ***00)

  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

以上就是我要为大家讲解的关于深入讲解游标类型为什么会产生数据检索的全部内容,希望能够对大家有所帮助。

【编辑推荐】

  1. oracle游标和游标变量的区别
  2. Oracle游标常用属性
  3. sql server遍历表不用游标和临时表的方法
责任编辑:迎迎 来源: 赛迪网
相关推荐

2009-12-18 18:10:55

Fedora proc

2015-06-10 16:24:42

数据检索

2024-07-16 08:03:43

2022-01-18 06:59:50

HashMap循环底层

2024-07-08 12:44:11

2009-11-09 09:34:07

WCF集合

2011-03-25 09:27:40

Oracle数据库回滚前退

2023-09-08 09:53:41

API开发

2019-08-30 10:27:37

数据库通信技术

2014-12-23 09:34:47

动态语言

2020-03-27 16:05:49

数据库数据MySQL

2022-05-18 08:25:59

MySQLutf8字符集数据库

2022-07-21 08:00:00

京东数据存储汽车行业

2024-01-24 09:00:00

2024-02-20 08:25:41

Redis内存数据库Python

2019-12-16 15:17:13

大数据信息安全数据库

2021-01-18 14:34:59

幂等性接口客户端

2011-08-16 09:07:06

2022-08-04 08:22:49

MySQL索引

2018-08-06 18:36:21

点赞
收藏

51CTO技术栈公众号