`
逆风的香1314
  • 浏览: 1431907 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多

表现:<o:p></o:p>

将数据库兼容级别从80 改到90 , 下面的游标循环不出数据, 但单独SELECT 有结果<o:p></o:p>

DECLARE MyCursor CURSOR LOCAL READ_ONLY<o:p></o:p>

FOR  <o:p></o:p>

SELECT<o:p></o:p>

    Col1<o:p></o:p>

FROM tbname WITH(NOLOCK) <o:p></o:p>

WHERE Name LIKE 'SNET%'<o:p></o:p>

    AND B_Key IN(<o:p></o:p>

            SELECT TOP(100)<o:p></o:p>

                KeyID<o:p></o:p>

            FROM tbmaster WITH(NOLOCK)<o:p></o:p>

            WHERE Date >= '<st1:chsdate isrocdate="False" month="1" day="1" islunardate="False" w:st="on" year="2007">01/01/2007</st1:chsdate>'<o:p></o:p>

                AND Date < '<st1:chsdate isrocdate="False" month="2" day="1" islunardate="False" w:st="on" year="2007">02/01/2007</st1:chsdate>')<o:p></o:p>

OPEN MyCursor<o:p></o:p>

FETCH NEXT FROM MYCURSOR<o:p></o:p>

WHILE (@@FETCH_STATUS=0)<o:p></o:p>

BEGIN<o:p></o:p>

    FETCH NEXT FROM MYCURSOR<o:p></o:p>

END<o:p></o:p>

CLOSE MyCursor<o:p></o:p>

DEALLOCATE MyCursor<o:p></o:p>

<o:p> </o:p>

分析:<o:p></o:p>

导致出现这个情况的原因是游标类型的问题.<o:p></o:p>

按照上述定义, 游标类型是: DYNAMIC<o:p></o:p>

定义这种游标的情况下, S 锁是必须下的, NOLOCK 提示不会起作用, 这个通过查询游标OPEN 时的sp_lock  信息可以观察得到. 它产生了IS S <o:p></o:p>

NOLOCK 提示是否起作用, 会影响的执行的结果(执行计划一样, 但在取数据的时候, 会有所差异)<o:p></o:p>

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

SELECT TOP(100)<o:p></o:p>

    KeyID<o:p></o:p>

FROM tbmaster WITH(NOLOCK)<o:p></o:p>

WHERE Date >= '<st1:chsdate isrocdate="False" month="1" day="1" islunardate="False" w:st="on" year="2007">01/01/2007</st1:chsdate>'<o:p></o:p>

    AND Date < '<st1:chsdate isrocdate="False" month="2" day="1" islunardate="False" w:st="on" year="2007">02/01/2007</st1:chsdate>')<o:p></o:p>

<o:p> </o:p>

在游标定义SELECT 语句中, NOLOCK 有效时, 是可以取到数据的, NOLOCK 无效(DYNAMIC 游标导致), 查询结果是无数据的<o:p></o:p>

所以最终看到的结果是: 游标循环不出来数据, 但只做查询却有数据.<o:p></o:p>

如果把游标定义中的查询语句的NOLOCK 去掉做查询, 也会没有数据(DYNAMIC 游标结果一致)<o:p></o:p>

<o:p> </o:p>

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

因为没有ORDER BY 保证顺序, 而有无NOLOCK 的数据可能不会一样, 所以理论上80 90 下都可能出现问题, 只是90 比较突出, 或者正好被发现了而已<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

解决的办法:<o:p></o:p>

把游标定义改成下面的, 这样不会导致NOLOCK 失效, 而且速度比原来的定义方式快得多. 如果游标一定要与原始表的数据变化关联起来, 建议用KEYSET, 或者是去掉NOLOCK 提示(因为没有意义),

分享到:
评论

相关推荐

    SQL SERVER 中游标的使用

    * 游标可能会导致数据的不一致性和数据的锁定问题。 * 游标可能会对数据库的安全性产生影响。 游标是一种非常有用的工具,它可以帮助我们更好地处理和操作数据。但是,我们需要正确地使用游标,并注意其规则和限制...

    MySQL海量数据查询优化策略.

    27. 使用FAST_FORWARD游标:当需要从存储过程中的游标快速检索数据时,使用FAST_FORWARD游标可以减少系统资源的消耗。 28. 关闭SET NOCOUNT:在执行SQL语句时,关闭SET NOCOUNT可以减少SQL Server返回额外信息的...

    oracle 临时表使用例子并用CURSOR返回结果集的例子

    现在,我们将利用游标(CURSOR)来演示如何从临时表中检索数据。游标是处理结果集的一种方式,它可以逐行处理数据,而不必一次性加载整个结果集。以下是一个使用游标返回临时表结果集的例子: ```sql DECLARE ...

    三级数据库样卷与标准答案.pdf

    分割表可能增加查询复杂度,但在检索特定部分数据时能提升性能。 【并行数据库拆分】 10. 对于整表扫描,范围划分(Range Partitioning)通常最有效,因为它允许并行处理每个分区。 【数据库系统的高可用性】 11...

    sqlserver和oracle数据迁移方案

    - **SELECT语句**:用于从数据库中检索数据。 - **INSERT语句**:用于向数据库中插入新行。 - **UPDATE语句**:用于更新已存在的数据。 - **DELETE语句**:用于从数据库中删除数据。 - **TRUNCATE TABLE语句**:与...

    PL/SQL的培训教程

    - **创建表、序列、视图和索引**: 表用于存储数据,序列用于自动产生唯一编号,视图提供对表的逻辑视图,索引用于加速数据检索速度。 - **Oracle数据字典**: 包含数据库元数据的信息集合,如数据库对象的定义、权限...

    oracle存储过程常用技巧

    游标是一种数据库对象,允许我们从数据集中逐行检索数据。在存储过程中,我们可以定义和使用游标来处理SELECT语句返回的结果集。游标可以在PL/SQL块内部进行声明和控制,例如打开、检索数据和关闭。 3. 异常处理: ...

    MySQL 45 道面试题及答案.docx

    游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。 三、存储过程(Stored Procedure) 存储过程,就是一些编译好了的...

    ORACLE 常用的SQL语法和数据对象

    4. **物化视图(Materialized View)**:预先计算好的视图,提供快速的数据检索。 5. **索引组织表(Index-Organized Table, IOT)**:数据直接存储在索引结构中,适用于频繁查询的表。 以上只是Oracle SQL语法和...

    oracle 详细讲解教程

    索引章节会探讨如何利用索引提高数据检索的速度,以及Oracle支持的索引类型,包括位图索引和函数式索引等。 序列和同义词在Oracle数据库中用于生成序列值和为数据库对象创建别名,这在数据管理和访问时提供了方便。...

    10g SQL 开发指南_脚本

    - 数据查询:通过SELECT语句,学习如何从数据库中检索数据,包括单表查询、多表联接、子查询以及使用聚合函数(如COUNT、SUM、AVG、MAX、MIN)进行统计计算。 - 数据插入:了解INSERT语句,掌握如何将新记录添加到...

    PLSQL程序设计.pdf (清晰版)

    - **4.1.2 处理隐式游标**:自动处理由查询产生的游标。 **4.1.3 关于NO_DATA_FOUND和%NOTFOUND的区别** NO_DATA_FOUND是预定义异常,用于处理没有数据的情况;%NOTFOUND是游标属性,用于检查游标是否到达末尾。 ...

    ASP。net、C#面试题

    索引和游标是数据库中两种重要的数据结构,它们在查询优化和数据检索方面扮演着关键角色。 **详细解释:** - **索引**:是一种数据结构,它提高了数据检索的速度。通过创建索引,数据库可以在表中快速定位特定的...

    超详细Oracle教程.pdf

    - 索引的创建和优化,提高数据检索速度。 - 序列和同义词的使用,实现自动编号和简化对象引用。 #### PL/SQL与编程元素 - PL/SQL编程语言介绍,包括变量、流程控制语句、异常处理等。 - 游标、函数和存储过程的编写...

    oracle 资料--图片存取

    存储和检索BLOB数据可能会对性能产生影响,因此,考虑使用索引(如B树索引或位图索引)、分区策略和缓存技术来提高效率。 10. **安全性**: 访问控制和权限管理是必要的,以确保只有授权用户可以存取和修改图片...

    plsql课件(北京航空航天大学)

    索引可以加速数据检索,而视图是虚拟表,可以简化复杂的查询并提供数据的抽象层。 9. **数据库连接和游标变量**: 在PLSQL中,我们可以使用DBMS_OUTPUT包来打印调试信息,或通过游标变量处理查询结果,实现更灵活...

    sql语句大全

    - 创建索引,提高数据检索速度。 - `CREATE SEQUENCE seq_name;` - 创建序列,用于自动产生唯一标识符。 以上是基于给定文件信息总结的SQL知识点,涵盖了SQL的基本操作、高级查询以及数据库对象管理等方面,对于...

Global site tag (gtag.js) - Google Analytics