Oracle ma wbudowany TRIM
funkcje dla ciągów. Zakładając, że masz ciąg taki jak '00012345'
i chcesz zachować go jako ciąg, a nie konwertować go na rzeczywisty NUMBER
, możesz użyć LTRIM
funkcja z opcjonalnym drugim set
parametr określający, że przycinasz zera:
select ltrim('000012345', '0') from dual;
LTRIM
-----
12345
Jeśli masz również spacje wiodące, możesz je przyciąć za jednym razem:
select ltrim(' 00012345', '0 ') from dual;
LTRIM
-----
12345
Możesz także przekonwertować na liczbę i odwrotnie, ale wydaje się to być dużo pracy, chyba że masz inne formatowanie, które chcesz usunąć:
select to_char(to_number('000012345')) from dual;
Nawiasem mówiąc, bezpośrednim powodem, dla którego otrzymujesz ORA-01722 za pierwszym razem, jest to, że używasz liczbowego +
operator zamiast operatora koncentracji ciągów Oracle ||
. Dokonuje niejawnej konwersji twojego łańcucha na liczbę, której wydaje się, że próbujesz uniknąć, a niejawna konwersja pojedynczej spacji - cokolwiek to jest - powoduje błąd. (Prawdopodobnie niektóre z Twoich wartości w rzeczywistości wcale nie są liczbami - kolejny przykład, dlaczego liczby powinny być przechowywane w NUMBER
pola; a jeśli tak jest, to konwersja (lub rzucanie) na liczbę i z powrotem nadal dałaby ORA-01722). Otrzymasz to samo w drugiej próbie, jeśli używasz LENGTH
zamiast LEN
. Żaden z nich i tak nie działałby jako INSTR
nie rozpoznaje wyrażeń regularnych. Możesz użyć REGEXP_INSTR
zamiast tego, ale lepiej byłoby, gdyby @schurik's REGEXP_REPLACE
wersję, jeśli chcesz przejechać tą trasą.
Nie jestem pewien, czy rozumiem Twoje pytanie edytuj. Wygląda na to, że wkładkę można uprościć do:
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 '));
(Nie rozumiem, dlaczego wykonujesz podzapytanie w swojej wersji lub dlaczego otrzymujesz przyciętą wartość od innego podzapytanie.)
Możesz także użyć 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);