【问题标题】:Transform Varchar2 data to number将 Varchar2 数据转换为数字
【发布时间】:2021-03-13 06:07:00
【问题描述】:

我有 x 列,类型为 varchar2(26),并将值存储为:

0.00, 1, 2, 0.5, 0.25 

我想将这些值作为数字数据复制到其他列,但出现错误:

ORA-01722:无效号码

我使用了以下代码:

ALTER TABLE tmp
ADD (x_1 NUMBER(3,2));

UPDATE tmp 
SET x_1 = to_number(x, '9.99');

【问题讨论】:

    标签: sql oracle11g oracle10g


    【解决方案1】:

    你可以使用:

    MERGE INTO tmp dst
    USING (
      WITH bounds ( x, rid, start_pos, end_pos ) AS (
        SELECT x,
               ROWID,
               1,
               INSTR( x, ',', 1 )
        FROM   tmp
      UNION ALL
        SELECT x,
               rid,
               end_pos + 1,
               INSTR( x, ',', end_pos + 1 )
        FROM   bounds
        WHERE  end_pos > 0
      )
      SELECT x,
             rid,
             start_pos,
             TO_NUMBER(
               CASE end_pos
               WHEN 0
               THEN SUBSTR( x, start_pos )
               ELSE SUBSTR( x, start_pos, end_pos - start_pos )
               END
             ) AS value
      FROM   bounds
    ) src
    ON ( src.rid = dst.ROWID AND src.start_pos = 1 )
    WHEN MATCHED THEN
      UPDATE SET x_1 = value
    WHEN NOT MATCHED THEN
      INSERT ( x, x_1 ) VALUES ( src.x, src.value );
    

    其中,对于样本数据:

    CREATE TABLE tmp (
      x VARCHAR2(26)
    );
    
    INSERT INTO tmp ( x ) VALUES ( '0.00, 1, 2, 0.5, 0.25' );
    
    ALTER TABLE tmp
    ADD (x_1 NUMBER(3,2));
    

    那么,合并之后:

    SELECT * FROM tmp;
    

    输出:

    X | X_1 :-------------------- | --: 0.00, 1, 2, 0.5, 0.25 | 0 0.00, 1, 2, 0.5, 0.25 | 1 0.00, 1, 2, 0.5, 0.25 | 2 0.00, 1, 2, 0.5, 0.25 | .5 0.00, 1, 2, 0.5, 0.25 | .25

    db小提琴here

    【讨论】:

      【解决方案2】:

      很明显,您的值不正确。您可以使用正则表达式仅更新有效值:

      UPDATE tmp 
          SET x_1 = to_number(x, '9.99')
          WHERE REGEXP_LIKE('^[0-9]?([.][0-9]{0,2})?$');
      

      【讨论】:

        【解决方案3】:

        根据您提供的数据,可以正常工作而不会出错。我假设您的数据比您显示的要多,并且“x”列中的一个值无法转换为数字。尝试这样的方法来识别这些问题值(我使用 -1 作为默认值,您需要选择一个未出现在表中的值):

        select
        x
        , to_number(x DEFAULT -1 ON CONVERSION ERROR, '9.99') x_1
        from tmp
        where to_number(x DEFAULT -1 ON CONVERSION ERROR, '9.99') = -1;
        

        更新

        抱歉 - 以上示例仅适用于 12c。找到问题数据的最简单方法可能只是使用一些 SELECT 语句来观察它,但是如果您想使用编码解决方案,那么无论 Oracle 版本如何,这都可能有效(调整“return -1”值以确保它是不是实际出现在数据中的值):

        CREATE or replace FUNCTION conv_to_num(x IN varchar) 
           RETURN NUMBER 
           IS conv_num NUMBER(3,2) := 0;
           BEGIN 
              conv_num := to_number(x, '9.99');
              return conv_num;
              exception
                WHEN OTHERS THEN
                    return -1;
            END;
        
        select
        x
        ,conv_to_num(x) x_1
        from tmp
        ;
        

        【讨论】:

        • 。 . ON CONVERSION ERROR 在 Oracle 11 和 10 中工作吗?
        【解决方案4】:

        我的问题是准确的。 x 列在下一行中有值,因此列看起来像

           x
        1 0.1
        2 0.25
        3 0.55
        4 2
        5 3
        6 1.25
        

        现在我需要相同的列,但数据类型为 NUMBER。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-10
          • 2021-03-18
          • 1970-01-01
          • 2018-07-11
          • 2021-10-03
          相关资源
          最近更新 更多