Удаление ведущих нулей из varchar sql developer
Как удалить ведущие нули из числа, которое находится в форме 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"
Я не уверен, как работать с отделкой (или литой) в инструкции выше. Какая-нибудь помощь? Спасибо за любую помощь!
3 ответов
Oracle имеет встроенный TRIM
функции для строк. Если у вас есть строка типа '00012345'
и вы хотите сохранить его как строку, а не преобразовать его в фактическое NUMBER
можно использовать LTRIM
функции с дополнительным вторым 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
версия, если вы хотите пойти по этому маршруту.
Я не уверен, что понимаю ваш вопрос edit. Похоже, ваша вставка может быть упрощена до:
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);
для SQL server, если вы знаете, что данные на самом деле число, вы можете просто привести его дважды. Кастинг на int
удаляет ведущие нули, а затем возвращается к строке для вставки. Я предполагаю, что вы можете сделать что-то подобное в Oracle.
DECLARE @vc varchar(100) = '0000000000000000000001234'
SELECT CAST(CAST(@vc as int) as varchar(100))
возвращает:
1234
вам не нужно его заменять. Он будет обрабатываться Oracle.
SELECT TO_NUMBER(num)
FROM
(
SELECT '00000123' AS num FROM DUAL
);
-- Result:
-- 123