先抛出一个问题:

我有一张表T,现在我想对表中1/4的记录作UPDATE操作,我的SQL如下:

Update t set col1='123' where mod(rownum,4)=1

我能够得到想要的结果吗?

答案是:不能。

我们通过一个实验来说明一下。

创建一个具有百万条记录的表:

使用mod(rownum,4)=1作谓词,计划更新全表1/4的记录

这张表有百万条记录,但该SQL操作feedback的结果竟然是"1 row updated",只有1条记录被更新。开什么玩笑?

UPDATE不行,那我换成查询怎么样呢?

仍然只有1条被查询到。那到底是什么原因导致了这个结果呢?为什么不是预期的1/4的记录呢?

这与ROWNUM伪列的实现机制有关。来看看Oracle官方是如何解释它的:

ROWNUM是指从表或集合中返回某条记录的顺序值,它只对最终返回的记录进行分配,未返回的记录不予分配(返回即表示将结果呈现给客户端)

这句话实际上仍然没有把它说清楚。下面是我自己的理解:类似于rownum<10或mod(rownum,4)=1这样的谓词是属于FILTER(过滤型)谓词,这种谓词需要对侯选集合(例如全表扫描后的侯选集合)进行过滤得到最终结果。在进行过滤操作时,每fetch一条记录,根据当前的返回顺序值预分配ROWNUM,当这条记录通过FILTER过滤并返回给客户端,该ROWNUM才实际分配给该条记录,并使当前返回值+1;如果这条记录未能通过过滤条件,该记录被丢弃,当前的返回顺序值不变化。

现在,我们用上面这段描述来说明上述案例仅返回1条记录的原因。

  1. 首先通过T表的全表扫描得到了侯选集合(不一定就是全表扫描,只是本例是通过全表扫描方式得到侯选集合。如下图)

  2. 从侯选集合中fetch一条记录,预分配ROWNUM=1,此时mod(1,4)=1,符合FILTER条件(mod(rownum,4)=1),该记录返回,并将ROWNUM=1实际分配给该记录,当前ROWNUM变为2
  3. 从侯选集合中fetch下一条记录,预分配ROWNUM=2,此时mod(2,4)=2,不符合FILTER条件,该记录被丢弃,当前ROWNUM不变化
  4. 此后将一直重复步骤3,直至侯选集合被完全遍历。
  5. 最终只有1条记录被返回。

可以通过一个微调进一步验证上述过程。如果把SQL改为:

select count(*) from t where mod(rownum,4)=2;

会有多少条记录返回呢?

答案是:一条也没有。

结论:

1、凡是涉及使用ROWNUM作为谓词条件的,一定要当心上述陷阱:凡是有可能使ROWNUM不能持续分配的操作、函数,均有可能导致类似现象。

转载于:https://www.cnblogs.com/6yuhang/p/8253007.html

Oracle ROWNUM的陷阱相关推荐

  1. oracle+rownum(),Oracle rownum和row_number()

    rownum 和 row_number()的区别 一. Oracle中的rownum 用于从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依次类推.这个伪字段可以用于限制查询返回的总行数,而 ...

  2. jsp分页技术用oracle实现,Oracle Rownum的使用与JSP分页显示的实现

    Oracle Rownum的使用与JSP分页显示的实现 徐越人 [期刊名称]<计算机与现代化> [年(卷),期]2007(000)010 [摘要]首先对Oracle的Rownum使用的诸多 ...

  3. oracle rownum最后的数据,oracle rownum问题

    本帖最后由 dingjun123 于 2011-11-16 20:06 编辑 你根本不了解oracle rownum的用法,详细参考sql reference 发个很久以前写的东西 8.rownum- ...

  4. oracle的rownum的用法,Oracle Rownum用法

    Oracle Rownum用法 Oracle提供了rownum,rownum是一个隐含的(查询结果集)字段,rownum是一个行号,从1开始. rownum隐含字段 select rownum, a. ...

  5. oracle rownum错乱,Oracle中RowNum的隐藏陷阱

    一.用RowNum来排序数据,或者生产FEntryId 有的时候我们习惯于这样使用RowNum Create table B as select RowNum as Fseq,Fnumber From ...

  6. oracle rownum 学习

    ----oracle排序写法 SELECT * FROM ( SELECT list.*, rownum as RNUM FROM ( SELECT * FROM CIP_Test_User ORDE ...

  7. ORACLE ROWNUM用法、select into与insert into区别、merge into的使用、递归查询

    ROWNUM用法 ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<. ...

  8. oracle rownum 特别慢,select * from table where rownum=1怎么会特别慢??表的数据在千万左右...

    援引我的blog的一篇文章. 这是一篇改写的文章,原文来自 http://www.db-nemec.com/Selecting_ROWNUM_1.html ,我只是结合我的实验重述,如果大家有时间,可 ...

  9. Oracle SQL篇(三)Oracle ROWNUM 与TOP N分析

        首先我们来看一下ROWNUM: 含义解释: 1.rownum是oracle为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推.这是一个伪列,可以用于限制查询返回的总行数. 2 ...

最新文章

  1. InfluxDB基本使用说明
  2. 内存申请与一级二级指针
  3. JavaScript实现四则运算
  4. python中的event_Python event
  5. 监控自定义信息 —— ESFramework 4.0 快速上手(10)
  6. 从零开始学前端:上节课案例+break,continue以及while和do while --- 今天你学习了吗?(JS:Day5)
  7. logic:equal,logic:present用法
  8. Linux基础学习笔记整理——第二章 管理文件和目录
  9. Oracle PL/SQL开发基础(第十五弹:同义词)
  10. GlassFish 理解
  11. ES 条形图 histogram
  12. 【Web3】什么是Web3?一个新的去中心化网络,或是最新的营销流行语
  13. 无线射频专题《射频信号,链路预算与衰落容限》
  14. 关于python数字的一种下划线奇怪写法
  15. 安装neurokit 的艰难历程
  16. 提升用户体验 联想企业网盘从速度、数据管理、业务协同三方面入手
  17. 模型可解释性-LIME
  18. 某厂向用户提供饲料matlab,Matlab习题
  19. C语言编程精粹读书笔记
  20. 经验风险最小化(Empirical Risk Minization,ERM)

热门文章

  1. SAP建议客户将UI技术迁移到Fiori的六大原因
  2. SAP CRM Fiori应用Simulation pipeline的刷新问题
  3. SAP CRM Appointment应用里Date profile的配置
  4. 在计算机应用领域 cad的指,在计算机应用领域,CAD的指的是____
  5. python概念英文版_python重要概念
  6. 疯狂html5+css3+javascript讲义 pdf_成为一名优秀的HTML5前端工程师需要掌握哪些技能?...
  7. can usb tool下载_N1内置CoreELEC、安卓多系统3.9.6.3版发布,更新下载链接
  8. es文件浏览器怎么用_es文件浏览器电视版下载-es文件浏览器电视tv版下载v4.2.3.4 安卓最新版...
  9. php mysql 双条件排序,PHP-MySQL联合查询,按2个变量排序
  10. js中every用法_js数组中的方法 some, every, filter, find,map, reduce讲解及使用场景