Oracle
 sql >> Base de données >  >> RDS >> Oracle

Suppression des zéros non significatifs du développeur varchar sql

Oracle a intégré TRIM fonctions pour les chaînes. En supposant que vous ayez une chaîne comme '00012345' et vous souhaitez le conserver sous forme de chaîne, et non le convertir en un NUMBER réel , vous pouvez utiliser le LTRIM fonction avec le second set facultatif paramètre spécifiant que vous rognez les zéros :

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

LTRIM
-----
12345

Si vous avez également des espaces de début, vous pouvez couper les deux en une seule fois :

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

LTRIM
-----
12345

Vous pouvez également convertir en nombre et inversement, mais cela semble demander beaucoup de travail à moins que vous n'ayez une autre mise en forme que vous souhaitez supprimer :

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

Incidemment, la raison immédiate pour laquelle vous obtenez l'ORA-01722 dès votre première tentative est que vous utilisez le numérique + au lieu de l'opérateur de concentration de chaîne d'Oracle || . Il effectue une conversion implicite de votre chaîne en un nombre, ce qu'il semble que vous essayez d'éviter, et la conversion implicite de l'espace unique - quel qu'il soit - est à l'origine de l'erreur. (Il est possible que certaines de vos valeurs ne soient pas du tout des nombres - un autre exemple de la raison pour laquelle les nombres doivent être stockés dans NUMBER des champs; et si tel est le cas, la conversion (ou la conversion) en un nombre et retour obtiendrait toujours l'ORA-01722). Vous obtiendriez la même chose à la deuxième tentative si vous utilisiez LENGTH au lieu de LEN . Ni l'un ni l'autre ne fonctionnerait de toute façon comme INSTR ne reconnaît pas les expressions régulières. Vous pouvez utiliser REGEXP_INSTR à la place, mais vous seriez mieux avec le REGEXP_REPLACE de @schurik version si vous vouliez emprunter cette voie.

Je ne suis pas sûr de comprendre votre question edit. Il semble que votre encart puisse être simplifié en :

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

(Je ne comprends pas pourquoi vous faites une sous-requête dans votre version, ou pourquoi vous obtenez la valeur coupée d'une autre sous-requête.)

Vous pouvez également utiliser 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);