一般而言,between和and的这种简单至极的东东是不会出错的,但是我还就试出了这个简单的东东的错误,暂且先这么叫,因为现在还不清楚oracle的内部实现机制,毕竟PL/SQL是第四代语言,怎么解析怎么编译怎么实现是oracle自己的事情。

背景:

一个表中有3000多万的数据需要迁移,以前的迁移脚本100W作为一个数据区间同步,相同的存储的过程就分了3000/100 = 30个,第一个存过的区间就写死成为BETWEEN 1 AND 1000000,第二个存过的区间就写死成为BETWEEN 1000001 AND 2000000,第3个第4个到第30都依此类推,稍微有点code常识的人看到这种代码都会悲从中来吧,提2个参数出来,能省多少活啊,大家一定要注意啊,不要只是简单的复制粘贴,这种代码写出来和只穿着三角裤上街没啥区别。

现在这种代码过了我手,我自然不能让这种东东继续丢人现眼,所以整了一下,提取了起始号和终止号作为入参,同样精简了另外2个同步700W数据和同步2000W数据的存过。

现在看起来就很美妙了,传参有更多的灵活性,重新测试700W和2000W数据的存过,发现一切OK,但是,注意,重点来了,在同步这个3000W数据的时候,我发现除了第一个[1,1000000]区间的存过能运行,其余的都hang那儿了,wait class 为 application,如果是I/Owait,还情有可原,但是application这种类型的wait,按照oracle给出的解释:

Waits resulting from user application code (for example, lock waits caused by row level locking or explicit lock commands)

可是我有给传参啊,所以可能就是行级锁了,出现行级锁,那就是可能有区间重合了,但是怎么可能重合呢,又仔细检查了存过,眼睛都看成斗鸡眼了,又请了几个同事帮忙看,还是没有发现有错误,再接着赋值测试,发现[1,1000000]和[1000001,2000000]果然有区间重合,在后者的区间居然把ID值为523456的找出来了,这个是怎么回事?又单独把sql语句拎出来查询,单独查询的就是好的,在[1000001,2000000]范围内...真是让人吐血啊,后来又修改表名,修改列的别名,修改表的别名一系列折腾,均告无果。

最后又怀疑是不是数据量太大导致溢出,于是又把3000W的表找了300W数据出来做测试,还是同样的问题,between and 越界,我现在已经非常非常想知道这个有参数的sql语句执行的时候到底是怎么回事了

SELECT M.ID,DECODE(M.TYPE,1,5,6) PORTSPEC,

M.NO CODE,M.MONIKERCODE AssembleCode,

M.PHYSTATUS,M.USESTATUS,M.SERVICESTATUS,

M.MDFPANELID,MP.COMMONMDFID,

1 CZLX, 'MDFCONNECTOR' NMSPEC,LS.ID syncid

FROM MDFCONNECTOR M,MDFPANEL MP,LRR_R3_MDFCONNECTOR LS

WHERE M.MDFPANELID = MP.ID

AND MP.CATEGORY IN (2,4)  --只有 2:横列,4:设备侧 下的端子同步到telant

AND M.TYPE IN(1,2)

AND M.ID = LS.NMID

AND LS.ISSYNC=2

AND LS.ID BETWEEN startNO

AND endNO

;

万幸的是新建的表由于没建索引,在执行的时候会锁一下,我总算能在sqlText中看oracle到底是怎么折腾这个sql语句的,如下:

SELECT M.ID,DECODE(M.TYPE,1,5,6) PORTSPEC,

M.NO CODE,M.MONIKERCODE AssembleCode,

M.PHYSTATUS,M.USESTATUS,M.SERVICESTATUS,

M.MDFPANELID,MP.COMMONMDFID,

1 CZLX, 'MDFCONNECTOR' NMSPEC,LS.ID syncid

FROM MDFCONNECTOR M,MDFPANEL MP,LRR_R3_MDFCONNECTOR LS

WHERE M.MDFPANELID = MP.ID

AND MP.CATEGORY IN (2,4)  --只有 2:横列,4:设备侧 下的端子同步到telant

AND M.TYPE IN(1,2)

AND M.ID = LS.NMID

AND LS.ISSYNC=2

AND LS.ID BETWEEN startNO

AND:B1

;

没错,我的2个参数,为毛只有1个参数了?starNO这个是要用1000001来代替的啊,应该是变量啊,而且更为诡异的是,这个语句丫居然不抛错,又把这个语句拎出去,把:B1替换为2000000执行了一下,居然能搜出值。但是单独找表 用select * from tablename where id between  startNO

and 2000000 来执行, 则会出错, 现在可以确认startNO

不是保留的数据了,难道是某一张表中的字段?果然,我的MDFPANEL表中有startNO字段,oracle随便找了这个字段中的第一值作为我的起始值了,所以所有的存过都是从相同的起始值开始的,行锁了.

这个问题现在就显得清晰,总结来说就是between and中有参数的话,要看这个参数名和表中的字段有没有重合的,如果重合了,以表列优先。

这个问题出现的偶然性很强,我个人觉得这种情况,oracle应该也抛出'有歧义'的错误,我不知道pl/sql的语法有没有详细阐述变量名和表列名的作用域谁大谁小的,今天花了一个下午解决这个问题,不想白白浪费,所以记之共享。

oracle select between and,oracle中的between和and的问题 | 学步园相关推荐

  1. oracle select执行顺序,oracle select执行顺序的详解

    oracle select执行顺序的详解 SQL Select语句完整的执行顺序:1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子 ...

  2. oracle select输出dbms,PLSQL 中如何使用 dbms_output 输出结果

    1.情景展示 在plsql中如何使用dbms_output输出执行结果? 如上图所示,运行后报错:ora-00922 2.原因分析 set serveroutput on 语句的作用是:打开Oracl ...

  3. oracle index include,oracle中与索引相关的视图—all_indexes | 学步园

    ALL_INDEXES描述了与索引有关的信息,为了使部分字段的内容更准确,我们需要通过analyze或者dbms_stats包来收集与索引有关的统计信息(这部分字段标记为带*). 首先看一下官网给出的 ...

  4. oracle select any dictionary oracle授权详解

    在使用oracle 9I em console客户端连接10G数据库时候,使用normal连接身份,会提示缺乏select any dictionary 权限.但是使用sysdba身份或者是用PL/S ...

  5. oracle离线文档查dbms_Oracle的健康检查–dbms_hm的使用 | 学步园

    这是oracle11g推出的一个新特性,利用这个特性我们可以提前预知一些问题,比如一张表上有个长时间未使用的坏块,在检测出来后我们可以提前修复,我们可以针对数据文件.控制文件.重做日志进行检测,当然我 ...

  6. oracle连接 无监听程序,“Oracle 连接报错:ORA-12541: TNS: 无监听程序”解决方案 | 学步园...

    环境描述: Oracle数据库部署在远程机器虚拟机上,本地配置Oracle网络配置,通过PL/SQL连接数据库: 本地已经配置了Oracle Net Manager文件,但是测试后,连接不上Oracl ...

  7. Java解决递归栈溢出_方法递归调用中java栈溢出的问题 及 解答 | 学步园

    为什么运行如下程序 , 方法sum2 不会导致栈溢出, 方法sum 会导致栈溢出? --------output----------- 32004000 java.lang.StackOverflow ...

  8. python float字节数_float型的数在内存中的表示 附:python3解析函数 | 学步园

    32为操作系统中float型的数是4个字节(32位),小数0.002122二进制格式如下: 00111011000010110001000101000001 左起第1位:是整个数的符号位,0正 1 负 ...

  9. java convert函数_自己实现 java中 Convert.toDouble(String str)处理函数 | 学步园

    今天在superWaba上看到Convert.toDouble(String str),由于底层问题比较大的数就出错,现在自己写了一个 程序中info()是我加的打印,可以去掉 java中 Conve ...

  10. matlab矩阵除以一个数字,matlab矩阵中每一行数除以一个数 | 学步园

    例如:用a中每一行数除以x中相对应的每一个数 x=[5 10 6 8 16 6 8 8 22 11]; a=[4 4 4 5 4 4 4 4 3 4 6 8 6 2 6 8 8 6 8 6 4 4 4 ...

最新文章

  1. Mac OS X Terminal 101:终端使用初级教程
  2. 如何搭建AIoT智能对话交互系统:技术解析和实操分享
  3. 学习面向对象的Javascript的第一步就是要搞清楚两个东西:原型链和作用域链
  4. linux硬盘类型怎么选,如何选择linux系统安装类型
  5. java使用elasticsearch进行模糊查询-已在项目中实际应用
  6. Cocos Creator学习のTiledMap
  7. ESP8266 驱动步进电机(28BYJ-48电机 ULN2003 驱动板)
  8. Android——ECG心电图的绘制实现
  9. 中国地质大学英语语音学习笔记(四):英语连读——弱读、冠词连读方法(包括元音字母前添加an的原因)和词间辅音加元音的连读方法
  10. 利用c#快速知道哪些qq好友空间屏蔽了自己
  11. 百度地图只显示指定的行政区域地图
  12. 计算机软考网络工程师 查询,计算机软考网络工程师考试成绩查询指南
  13. Hive考试练习题前75分答案
  14. CGB2105-Day09
  15. Linux 命令 htop 的使用
  16. kubernetes的Service Account和secret关系
  17. CityEngine中的坐标系统
  18. php soapclient 异常,一个请求后,PHP SoapClient失败
  19. 《Python编程:从入门到实践》第二章练习题
  20. 苹果手机最新款什么时候上市_为什么iPhone XR拥有苹果手机中最强的续航能力?...

热门文章

  1. 62. Event shiftKey 事件属性
  2. 4. laravel 路由(1)
  3. 3. laravel 包含头尾文件
  4. li:hover与a:hover的区别
  5. 20190316 学习程序最重要的是思考,不是你会多少技能
  6. Codeforces 19E 树上差分
  7. getElementById和ByTagName的区别
  8. 用shell查找某目录下的最大文件
  9. eclipse 使用问题
  10. MySQL 中随机抽样:order by rand limit 的替代方案