123
返回列表 发新帖
楼主: wqliu

[PL/SQL] ora-01722,invalid number 百思不解,敬请各位大师解决

[复制链接]
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
21#
 楼主| 发表于 2020-5-1 20:37 来自手机 | 只看该作者
我刚在9i  9.2.0.1试过没有问题

使用道具 举报

回复
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
22#
 楼主| 发表于 2020-5-1 22:17 来自手机 | 只看该作者
难道是版本的问题?

使用道具 举报

回复
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
23#
 楼主| 发表于 2020-5-4 08:26 | 只看该作者
不是版本的问题.
刚回到公司,
1....create table AAA as  select   *from G_PRINT_PALLET_MORE ;
2.....
select T1.* from (
  select to_number(substr(parame_name,4)) as parame_name1 , a.* from SAJET.AAA a
  where substr(parame_name,0,3) = 'SN_' and parame_name != 'SN_COUNT' and parame_name != 'SN_END'
  )T1
  where to_number(T1.parame_name1) between 400 and 420;

是没有任何问题的.
或者, 把导出来的数据 插入到AAA,也一样没有问题.


问题到底在哪儿呢

使用道具 举报

回复
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
24#
 楼主| 发表于 2020-5-4 09:36 | 只看该作者
可以结贴了.

用oracle 的正则表达式可解决.


     select T1.parame_name1  from (
  select substr(parame_name,4) as parame_name1 , a.* from SAJET.a_test2 a
  where substr(parame_name,0,3) = 'SN_' and parame_name != 'SN_COUNT' and parame_name != 'SN_END'
  )T1
  where  regexp_substr(parame_name1,'[0-9]+')  between 400 and 420;

使用道具 举报

回复
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
25#
 楼主| 发表于 2020-5-4 09:46 | 只看该作者
sql plan

123.png (35.37 KB, 下载次数: 51)

123.png

使用道具 举报

回复
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
26#
发表于 2020-5-6 10:22 | 只看该作者
本帖最后由 sqysl 于 2020-5-6 10:24 编辑

这个贴虽然楼主结贴,但问题依然没有解决,或者没解释清楚,那么,我来解释下:
1、之前楼主的SQL语句之所以报错,是因为SQL生成执行计划阶段,对子查询进行了合并,并将最外面报错的where条件和子查询中的where条件进行了合并,这点从楼主提供的执行计划就可以看出来,这样,合并进来的报错的where条件先进行过滤时,就会发生报错,因为这时之前子查询中的where条件可能还没发生作用;
2、楼主用正则函数避免了报错的问题,是因为这个正则函数和to_number不是等价的,它只是找出了包含一位数字的数据行,所以不报错;
3、根据上面的分析,楼主也可以禁止子查询展开试试,那样就应该不报错了。

使用道具 举报

回复
论坛徽章:
4
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21
27#
 楼主| 发表于 2020-5-6 23:56 来自手机 | 只看该作者
谢谢您的精彩分析。确实是full scan做了合并,导致子查询没起到作用,那如何做到禁止子查询展开呢

使用道具 举报

回复
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
28#
发表于 2020-5-7 09:50 | 只看该作者
wqliu 发表于 2020-5-6 23:56
谢谢您的精彩分析。确实是full scan做了合并,导致子查询没起到作用,那如何做到禁止子查询展开呢

你可以在子查询中用group分组或rownum之类的,也可以用no_merge等hint试试看。

使用道具 举报

回复
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
29#
发表于 2020-5-8 09:59 | 只看该作者
例如:
select /*+ no_merge(T1)*/  T1.* from (
  select to_number(substr(parame_name,4)) as parame_name1 , a.* from SAJET.G_PRINT_PALLET_MORE a
  where substr(parame_name,0,3) = 'SN_' and parame_name != 'SN_COUNT' and parame_name != 'SN_END'
  )T1
  where to_number(T1.parame_name1) between 400 and 420;

使用道具 举报

回复
论坛徽章:
5
2014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02优秀写手
日期:2014-10-22 06:00:13秀才
日期:2016-12-21 16:55:07秀才
日期:2017-08-18 11:06:45
30#
发表于 2020-5-15 13:33 | 只看该作者
说到底还是数据问题

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表