Oracle SQL:将Varchar2转换为Number并处理Null

时间:2017-09-04 10:06:22

标签: sql oracle

我需要将CUSER1列从VARCHAR2转换为NUMBER。下面是我正在使用的当前SQL,看看我是否可以让他上班:

SELECT V_PDAYPROD_CRW1.MFGCELL     ,
   V_PDAYPROD_CRW1.MFG_TYPE     ,
   V_PDAYPROD_CRW1.PROD_DATE,
   V_PDAYPROD_CRW1.EQNO,
   V_PDAYPROD_CRW1.SHIFT,
   V_PDAYPROD_CRW1.ARINVT_ID,
  NVL(AVG(
    TO_NUMBER(NVL(V_PDAYPROD_CRW1.CUSER1,0),9999.99)
    ),0) CUSER1    

FROM V_PDAYPROD_CRW1
     LEFT JOIN 
     (
      SELECT REJECTS.DAY_PART_ID D_P_ID,
      SUM(REJECTS.REJECTS) RE
      FROM REJECTS
      GROUP BY REJECTS.DAY_PART_ID
     )
      ON V_PDAYPROD_CRW1.PDAY_PART_ID = D_P_ID


GROUP BY  V_PDAYPROD_CRW1.MFGCELL     ,
      V_PDAYPROD_CRW1.MFG_TYPE     ,
      V_PDAYPROD_CRW1.PROD_DATE,
      V_PDAYPROD_CRW1.EQNO,
      V_PDAYPROD_CRW1.SHIFT,
      V_PDAYPROD_CRW1.ARINVT_ID

我一直收到错误ORA-01722: invalid numberCUSER1中的值主要是:NULL,5,0.33,.25,1,.1,0.42等......

我正在尝试使用TO_NUMBER()来做这件事,但我似乎无法做到正确。

有什么建议吗?

  

更新我尝试将VARCHAR2转换为NUMBER。仍然获得无效号码

SELECT V_PDAYPROD_CRW1.MFGCELL     ,
   V_PDAYPROD_CRW1.MFG_TYPE     ,
   V_PDAYPROD_CRW1.PROD_DATE,
   V_PDAYPROD_CRW1.EQNO,
   V_PDAYPROD_CRW1.SHIFT,
   V_PDAYPROD_CRW1.ARINVT_ID,

   NVL(AVG(CAST(V_PDAYPROD_CRW1.CUSER1 AS NUMBER) ),0) CUSER1        

FROM V_PDAYPROD_CRW1
     LEFT JOIN 
     (
      SELECT REJECTS.DAY_PART_ID D_P_ID,
      SUM(REJECTS.REJECTS) RE
      FROM REJECTS
      GROUP BY REJECTS.DAY_PART_ID
     )
      ON V_PDAYPROD_CRW1.PDAY_PART_ID = D_P_ID

GROUP BY  V_PDAYPROD_CRW1.MFGCELL     ,
      V_PDAYPROD_CRW1.MFG_TYPE     ,
      V_PDAYPROD_CRW1.PROD_DATE,
      V_PDAYPROD_CRW1.EQNO,
      V_PDAYPROD_CRW1.SHIFT,
      V_PDAYPROD_CRW1.ARINVT_ID
  

更新:搞定了

我正在使用以下功能来实现它:

COALESCE(TO_NUMBER(REGEXP_SUBSTR(V_PDAYPROD_CRW1.CUSER1, '^\d+')), 0)

这让我得到了我想要的结果。感谢@Thorsten_Kettner指导我找到合适的解决方案。

2 个答案:

答案 0 :(得分:1)

转换可能会失败。 0.33不是所有语言的有效数字。

您可以将该点明确指定为小数分隔符:

to_number(cuser1, '99999.999')

也许你甚至不得不削减空白:

to_number(trim(cuser1), '99999.999')

但仍有可能存在违反该模式的价值观。然后WHERE子句可能有助于仅转换有效数字。 E.g:

where regexp_like(cuser1, '^[[:digit:]]*\.{0,1}[[:digit:]]*$') or cuser1 is null

答案 1 :(得分:0)

NVL(AVG(
TO_NUMBER(NVL(V_PDAYPROD_CRW1.CUSER1,'0'),'9999.99')
),0) CUSER1  

试试这个..