今天发现了decode一个很奇怪的,也比较有趣的问题。。不太名字的oracle 对decode的解析机制,帮忙大侠帮忙,
不好意思,小弟分不够,有兴趣的大侠看看,知道的帮忙解下小弟疑惑。    
   select decode(length('C20090002'),8,to_number('c20090002')+1
       ,substr('C20090002',1,1)||to_char(substr('C20090002',2)+1) )
   from dual   select decode(length('C20090002'),9,substr('C20090002',1,1)||to_char(substr('C20090002',2)+1) 
       ,to_number('c20090002')+1)
   from dual同样的俩句查询,只是顺序同,但是第一句执行时就报错奇怪了。

解决方案 »

  1.   

    to_number('c20090002')这个必定报错的
    第二句通过语法检查后,只要length('C20090002')=9,就不会执行到to_number('c20090002')+1部分,没出错是暂时的
      

  2.   

    to_number('c20090002')里面的有字符
    肯定不能用to_number
      

  3.   

    decode就相当于java中的swicth……case,是进行等值的if……else判断的。
    错不是错在decode函数,而是错在转换函数to_number,它可以把字符转换为数字,但前提必须是:必须是由数字组成的字符,也就是说字必须可以转换成数字才行。
      

  4.   

    之前没有仔细看,大家都搞错了,第一句报错并不是to_number('c20090002')+1这个地方,因为length('C20090002')的值是9而不是8,to_number('c20090002')+1这句是不会执行的。
    报错的是后面的substr('C20090002',1,1)||to_char(substr('C20090002',2)+1)的这个位置。把红色的那个1换成其它的(如7或3等等)就不会错了。报错是因为substr('C20090002',1,1)||to_char(substr('C20090002',2)+1)的数据类型和length('C20090002')的数据类型不一致造成的。--如下两个例子
    select decode(length('C20090002'),8,to_number('c20090002')+1 
          ,'7657' ) 
      from dual;--没错
     select decode(length('C20090002'),8,to_number('c20090002')+1 
          ,'76d5d7' ) 
      from dual--报错
      

  5.   

    再补充一下,默认值(substr('C20090002',1,1)||to_char(substr('C20090002',2)+1))的数据库型也不一定要与第一个参数(length('C20090002'))的相同,但必须得与第一个条件后面的那列(to_number('20090002')+1 )的数据类型相同或者能转换成功的数据类型。