网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
本月文章推荐
.oracle中使用ANYDATA列对数据串行.
.ORACLE性能诊断―学习statspack笔.
.构建您自己的Oracle RAC 10g集群.
.Oracle回滚表空间数据文件误删除.
.Oracle数据库的转移与升级.
.案例学习Oracle错误:ORA-27123.
.Oracle rac安装过程详解(一).
.用CREATE TABLE陈述式声明计算数.
.PROC++批量导入导出ORACLE数据.
.oracle重装时问题解决方案.
.开机流程与关机、档案系统.
.编写一个接受变量的存储过程.
.Oracle9i初始化参数中文说明(一.
.在9i里对基于函数的索引进行仅索.
.构建用于位置信息开放标准的Port.
.关于block中行数据的存储与空间重.
.一个将数据分页的存储过程.
.ORACLE9i新特性—索引跳跃式扫描.
.让你的连接查询加速.
.在多个目录之中自动搜索需要的文.

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

发表日期:2008-4-9


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

现象:

在将数据库兼容的级别从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

上一篇:调用存储过程时注意要使用output做修饰符 人气:1337
下一篇:怎样才能提高Oracle 10G增量备份速度 人气:868
浏览全部Oracle的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐