如何从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);
我现在得到一个错误,因为我的trim函数返回多行结果。
Error report:
SQL Error: ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
我不确定如何在上面的陈述中使用修剪(或演员)。对此有何帮助? 谢谢你的帮助!
答案 0 :(得分:33)
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);
答案 1 :(得分:1)
对于SQL Server,如果您知道数据实际上是一个数字,则可以将其强制转换两次。转换为int
会删除前导零,然后返回到字符串以进行插入。我假设你可以在Oracle中做类似的事情。
DECLARE @vc varchar(100) = '0000000000000000000001234'
SELECT CAST(CAST(@vc as int) as varchar(100))
返回:
1234
答案 2 :(得分:1)
您无需更换它。它将由Oracle处理。
SELECT TO_NUMBER(num)
FROM
(
SELECT '00000123' AS num FROM DUAL
);
-- Result:
-- 123
答案 3 :(得分:0)
您可以使用以下方法:
选项 1:使用 ltrim 函数,正如 Alex 所说:
select ltrim('0005400', '0')
from dual;
选项 2:使用修剪功能:
select trim(leading '0' from '0005400')
from dual;
Oracle 修剪函数有前导、尾随和两个选项。
选项 3:使用正则表达式:
select regexp_substr('0005400', '[^0].+')
from dual;