【问题标题】:Removing leading zeros from varchar sql developer从 varchar sql developer 中删除前导零
【发布时间】:2022-01-13 14:43:49
【问题描述】:

如何从 varchar 形式的数字中删除前导零。 我尝试了以下方法:

选项 1:

insert into example_table (columnName) 
    (SELECT
        SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '), 10)
        from columnName2);

这样,我得到的错误是

SQL Error: ORA-01722: invalid number
ORA-02063: preceding line from xxxx
01722. 00000 -  "invalid number"

选项 2:

insert into example_table (columnName) 
    (SELECT
        SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '),  
        LEN(columnName2))
     from columnName2);

这次我明白了

Error at Command Line:23 Column:87
Error report:
SQL Error: ORA-00904: "LEN": invalid identifier

选项 3:

SUBSTRING
    (columnName2, PATINDEX('%[^0 ]%', columnName2 + ' '), 10));

与上面类似,我明白了

Error at Command Line:23 Column:41
Error report:
SQL Error: ORA-00904: "PATINDEX": invalid identifier
00904. 00000 -  "%s: invalid identifier"

编辑

我认为修剪路线可能是我最好的选择,但是......我不确定在我有的情况下如何使用它。

INSERT INTO temp_table
(columnNeedTrim, column2, column3, column4, column5) 
    SELECT * FROM
        (SELECT(
      SELECT TRIM(leading '0' from columnNeedTrim) FROM table),
            table.column2, 
            table2.column3,
                table.column4
                table.column5
        FROM
        table 
        INNER JOIN 
        table2 ON
            table1.columnNeedTrim=table2.columnNeedTrim) 
    WHERE NOT EXISTS (SELECT * FROM temp_table);

我现在收到一个错误,因为我的修剪函数返回多行结果。

Error report:
SQL Error: ORA-01427: single-row subquery returns more than one row
01427. 00000 -  "single-row subquery returns more than one row"

我不确定如何在上面的语句中使用修剪(或演员表)。有什么帮助吗? 感谢您的帮助!

【问题讨论】:

  • 这也适用于 SQL Server 2008 吗?您已将其标记为此类,但刚刚被其他人删除。
  • 它是为 SQL 开发人员准备的...并不是要为服务器 2008 标记

标签: sql oracle


【解决方案1】:

Oracle 为字符串内置了TRIM 函数。假设您有一个类似'00012345' 的字符串,并且您希望将其保留为字符串,而不是将其转换为实际的NUMBER,您可以使用LTRIM function 和可选的第二个set参数来指定您正在修剪零:

select ltrim('000012345', '0') from dual;

LTRIM
-----
12345

如果您可能还有前导空格,则可以一次性修剪两个:

select ltrim(' 00012345', '0 ') from dual;

LTRIM
-----
12345

您也可以转换为数字并返回,但这似乎需要大量工作,除非您有其他要删除的格式:

select to_char(to_number('000012345')) from dual;

顺便说一句,您从第一次尝试中得到 ORA-01722 的直接原因是您使用数字 + 运算符而不是 Oracle 的字符串浓缩运算符 ||。它正在将您的字符串隐式转换为数字,这似乎是您试图避免的,并且单个空格的隐式转换 - 无论是什么 - 都会导致错误。 (实际上,可能您的某些值根本不是数字 - 为什么数字应存储在 NUMBER 字段中的另一个示例;如果是这种情况,那么转换(或转换)为数字并返回仍然会得到ORA-01722)。如果您使用LENGTH 而不是LEN,那么您在第二次尝试中会得到同样的结果。无论如何都不会工作,因为INSTR 不识别正则表达式。您可以改用REGEXP_INSTR,但如果您想走这条路,最好使用@schurik 的REGEXP_REPLACE 版本。


我不确定我是否理解您的问题编辑。看起来您的插入可以简化为:

INSERT INTO temp_table (columnNeedTrim, column2, column3, column4, column5)
SELECT LTRIM(table1.columnNeedTrim, '0 '),
    table1.column2,
    table1.column3,
    table1.column4,
    table1.column5
FROM table1
INNER JOIN table2 ON table2.columnNeedTrim = table1.columnNeedTrim
WHERE NOT EXISTS (
    SELECT * FROM temp_table
    WHERE columnNeedTrim = LTRIM(t42.columnNeedTrim, '0 '));

(我不明白您为什么要在您的版本中执行子查询,或者为什么您要从 另一个 子查询中获取修剪后的值。)

你也可以使用MERGE:

MERGE INTO temp_table tt
USING (
    SELECT LTRIM(t42.columnNeedTrim, '0 ') AS columnNeedTrim,
        t42.column2,
        t42.column3,
        t42.column4,
        t42.column5
    FROM t42 
    INNER JOIN t43 ON t43.columnNeedTrim=t42.columnNeedTrim
) sr
ON (sr.columnNeedTrim = tt.columnNeedTrim)
WHEN NOT MATCHED THEN
INSERT (tt.columnNeedTrim, tt.column2, tt.column3, tt.column4, tt.column5)
VALUES (sr.columnNeedTrim, sr.column2, sr.column3, sr.column4, sr.column5);

【讨论】:

  • 我在进行更多研究时发现了这一点...但是我遇到了另一个错误...我将在编辑中发布结果...
  • @user1998581 - 我想我可能遗漏了一些重要的东西,或者问题遗漏了一些东西,但我添加了一个更简单的插入语句......
  • 我从两个不同的表(table1 和 table2 并插入它们的连接(因为我需要它们在一行中)只有当它不存在于 temp_table alraedy 时...我必须采取一列(columnNeedTrim)并修剪前导零,因为 temp_table 中的值已修剪它们......因此它无法识别数字是否相同,因为一个有前导零而一个没有......这有什么意义?
  • 好的,但是您的 not exists 子句中缺少这一点。我已经更新了我的以显示这一点。我还添加了merge 版本。
  • 它似乎在工作。太感谢了。我进行不需要的子查询的原因很简单,因为我对 sql 是半新的,这是我认为它可以工作的唯一方法。
【解决方案2】:

对于 SQL Server,如果您知道数据实际上是一个数字,则可以将其转换两次。转换为 int 会删除前导零,然后返回字符串以进行插入。我假设你可以在 Oracle 中做类似的事情。

DECLARE @vc varchar(100) = '0000000000000000000001234'

SELECT CAST(CAST(@vc as int) as varchar(100))

返回:

1234

【讨论】:

  • 我如何将它应用到整行而不只是一个变量?
  • 您得到的数字无效,因为您的值不是整数。
【解决方案3】:

您不必更换它。它将由 Oracle 处理。

SELECT  TO_NUMBER(num)
FROM
(
        SELECT '00000123' AS num FROM DUAL
);

-- Result:
-- 123

【讨论】:

  • 除非他有一个领先的空间或其他东西 - 我怀疑他对@JNK回答的其他评论
  • @DanAndrews - 前导空格不是问题,但不清楚是否有其他值根本不代表数字,因此会生成 ORA-01722。
【解决方案4】:

您可以使用以下方法:

选项 1:使用 Alex 所说的 ltrim 函数:

select ltrim('0005400', '0')
  from dual;

选项2:使用修剪功能:

select trim(leading '0' from '0005400')
  from dual;

Oracle trim 函数有前导、尾随和这两个选项。

选项3:使用正则表达式:

select regexp_substr('0005400', '[^0].+')
  from dual;

【讨论】:

    【解决方案5】:
    SELECT '00012345' AS zeroWith, TRIM(LEADING 0 FROM '00012345') AS zeroWithOut
      FROM dual;
    

    结果:zeroWith > 00012345 & zeroWithOut > 12345

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2018-06-16
      • 1970-01-01
      • 2010-09-10
      相关资源
      最近更新 更多