有关verchar2型的纯数字和纯数字与杠“-”组合的大小比较问题

问题描述:

如上图所示,数据库中表v_person里的字段 person_code(verchar2(32))的数据有这样的几种形式。


查询条件:
    person_code 范围:1 到 10


要完成的任务:
1. 返回结果一: 将表中所有person_code为纯数字的记录并且person_code的值在范围 1 到 10 之间的记录查出来,即:1,2,3,4,5,6,7,8,9,10。

2. 返回结果二:将表中所有person_code为“47-A”这样的形式,也就是说,“-”前面是纯数字的,并且,“-”前面的数字值在范围 1 到 10 之间的记录查出来,如:1-A,02-A等等。



在做的过程中,从失败到成功,所有用到的语句和出现的问题如下:
尝试一:
select t.person_code, t.person_name, t.org_Cname
  from v_report_person t
where 1 = 1
   and t.person_code >= '1'
   and t.person_code <= '10'
   and ((1 = 1 and length(t.person_code) >= length('1') and
       length(t.person_code) <= length('10')) or
       (1 = 1 and instr(t.person_code, '-') - 1 >= length('1') and
       instr(t.person_code, '-') - 1 <= length('10')))
order by decode(instr(t.person_code, '-'),
                 0,
                 LENGTH(t.person_code),
                 instr(t.person_code, '-') - 1),
          t.person_code;


这样的语句,返回的只有两条数据:person_code =1  和  person_code=10只有这两条。
因此,我明白了,这条语句它认为  2比10大,后来,我换数据尝试确实认证了这个想法。

尝试二:
select *
from v_report_person t
where FUN_ISNUMBER(t.person_code) != 0--所有person_code为纯数字的记录
and t.person_code >= '1'
and t.person_code <= '10'
and length(t.person_code) >= length('1') 
and length(t.person_code) <= length('10')


ps:FUN_ISNUMBER代码:
--检查是否数字型
function FUN_ISNUMBER(
 P_VALUE  varchar2--输入参数
 ) return  number is
  LL_VALUE number;
   begin
    LL_VALUE := TO_NUMBER(P_VALUE);   
     return LL_VALUE;  
     exception    when others then  
       return 0;------如果不是返回0 
  end FUN_ISNUMBER;


这样的尝,得到的仍是两条记录:person_code =1  和  person_code=10


以上是最主要的两种尝试,其他的试过to_number,convert,cast还有其他一些我能想到的方法。最终还是失败了。

select *
from v_report_person t
where PKG_BASE_UTIL.FUN_ISNUMBER(t.person_code) != 0
and to_number(t.person_code) >= 1
and to_nubmer(t.person_code )<= 10
and length(t.person_code) >= length('1') 
and length(t.person_code) <= length('10')

这样尝试,报错:
有关verchar2型的纯数字和纯数字与杠“-”组合的大小比较问题



搞了好几天,也没解决问题(   也许高手看了感觉再简单不过了,可是俺就不行了,要么怎么会有高手和菜鸟之说呢):


最后,我问了我一个朋友,和他讨论了半天,他也出了许多方式,最后他问了句:“你那个单引号,去掉了会报错吗?”

我就赶紧试了试,说实在话,我试了那么多次,  to_number(t.person_code) >= 1 和 t.person_code >= '1'  ,唯独没有试过 t.person_code >= 1


结果出来了,竟然出来了。

曾经那种思维定势,非要to_number(t.person_code) >= 1这样去比较,结果碰了钉子。

竟然因为一个“单引号”,在死坛中出不来。


症结一打开,很快,我就搞定了,我想要的结果:
select t.person_code,t.person_name,t.org_Cname from (select *
from v_report_person t
where (pkg_base_util.FUN_ISNUMBER(t.person_code) != 0
and t.person_code >= 1
and t.person_code <= 50
and length(t.person_code) >= length(1) 
and length(t.person_code) <= length(50)) 
union all
select *from v_report_person t
where pkg_base_util.FUN_ISNUMBER(substr(t.person_code, 1,instr(t.person_code, '-') - 1)) != 0
and length(substr(t.person_code, 1,instr(t.person_code, '-') - 1)) >= length(1) 
and length(substr(t.person_code, 1,instr(t.person_code, '-') - 1)) <= length(50) 
and to_number(substr(t.person_code, 1,instr(t.person_code, '-') - 1))>=1
and to_number(substr(t.person_code, 1,instr(t.person_code, '-') - 1))<=50) t 
order by decode(instr(t.person_code, '-'), 0, LENGTH(t.person_code),instr(t.person_code, '-') - 1),t.person_code;


我得到了我想要的结果如图:

有关verchar2型的纯数字和纯数字与杠“-”组合的大小比较问题



1. 返回结果一: 将表中所有person_code为纯数字的记录并且person_code的值在范围 1 到 50 之间的记录查出来。

2. 返回结果二:将表中所有person_code为“47-A”这样的形式,也就是说,“-”前面是纯数字的,并且,“-”前面的数字值在范围 1 到 50 之间的记录查出来,如:1-A,02-A等等。





特记下这个过程,以便以后追忆。    



后记:上面的语句还是不行,超过3位的就会出错,就是说把50变成100后就会出错,不解。


后来请高手解决了,答案补充如下:
          
     select *
        from t_md_person t
       where (decode(FUN_ISNUMBER(t.person_code),
                     0,
                     decode(FUN_ISNUMBER(substr(t.person_code,
                                                              1,
                                                              instr(t.person_code,
                                                                    '-') - 1)),
                            0,
                            -999999999999,
                            to_number(substr(t.person_code,
                                             1,
                                             instr(t.person_code, '-') - 1))),
                     to_number(t.person_code)) >= 1 and
             decode(FUN_ISNUMBER(t.person_code),
                     0,
                     decode(FUN_ISNUMBER(substr(t.person_code,
                                                              1,
                                                              instr(t.person_code,
                                                                    '-') - 1)),
                            0,
                            999999999999,
                            to_number(substr(t.person_code,
                                             1,
                                             instr(t.person_code, '-') - 1))),
                     to_number(t.person_code)) <= 100)
       order by decode(instr(t.person_code, '-'),
                       0,
                       LENGTH(t.person_code),
                       instr(t.person_code, '-') - 1),
                t.person_code;


你可能感兴趣的:(sql)