sql >> Database >  >> RDS >> Oracle

Voorloopnullen verwijderen uit varchar sql-ontwikkelaar

Oracle heeft ingebouwde TRIM functies voor strings. Ervan uitgaande dat je een string hebt zoals '00012345' en je wilt het als een string behouden, niet converteren naar een echt NUMBER , kunt u de LTRIM . gebruiken functie met de optionele tweede set parameter die aangeeft dat u nullen bijsnijdt:

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

LTRIM
-----
12345

Als u ook voorloopspaties heeft, kunt u beide in één keer inkorten:

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

LTRIM
-----
12345

Je zou ook kunnen converteren naar een getal en terug, maar dat lijkt veel werk, tenzij je een andere opmaak hebt die je wilt verwijderen:

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

Overigens is de directe reden dat u de ORA-01722 bij uw eerste poging krijgt, dat u de numerieke + gebruikt operator in plaats van Oracle's stringconcentratie-operator || . Het doet een impliciete conversie van je string naar een getal, wat je lijkt te vermijden, en de impliciete conversie van de enkele spatie - waar die ook voor is - veroorzaakt de fout. (Mogelijk zijn sommige van uw waarden in feite helemaal geen getallen - nog een voorbeeld van waarom getallen moeten worden opgeslagen in NUMBER velden; en als dat het geval is, dan zou het converteren (of casten) naar een nummer en terug de ORA-01722) krijgen. Je zou hetzelfde krijgen bij de tweede poging als je LENGTH zou gebruiken in plaats van LEN . Geen van beide zou hoe dan ook werken als INSTR herkent geen reguliere expressies. Je zou REGEXP_INSTR . kunnen gebruiken in plaats daarvan, maar je zou beter af zijn met @schurik's REGEXP_REPLACE versie als je die route wilt volgen.

Ik weet niet zeker of ik je vraag begrijp, edit. Het lijkt erop dat uw invoeging kan worden vereenvoudigd tot:

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 '));

(Ik begrijp niet waarom u een subquery uitvoert in uw versie, of waarom u de ingekorte waarde van een andere krijgt subquery.)

U kunt ook MERGE . gebruiken :

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. Waarom zijn geaggregeerde functies niet toegestaan ​​in de where-clausule?

  2. Mysql-query om rijen dynamisch naar kolommen te converteren

  3. Schemapatroon zoeken

  4. Grote objecten mogen niet worden gebruikt in de modus voor automatisch vastleggen