Erreur SQL "ORA-01722: numéro non valide"

101

Un très facile pour quelqu'un, L'encart suivant me donne le

ORA-01722: numéro invalide

Pourquoi?

INSERT INTO CUSTOMER VALUES (1,'MALADY','Claire','27 Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (2,'GIBSON','Jake','27 Smith St Caulfield','0415 713 598');
INSERT INTO CUSTOMER VALUES (3,'LUU','Barry','5  Jones St Malvern','0413 591 341');
INSERT INTO CUSTOMER VALUES (4,'JONES','Michael','7  Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (5,'MALADY','Betty','27 Smith St Knox','0418 418 347');
Phillip Gibson
la source
28
Alors ... à quoi sert la définition de table CUSTOMER? Vous n'avez donné que la moitié des informations nécessaires.
Greg Hewgill
3
Les numéros de téléphone sont la seule chose qui pourrait raisonnablement être définie comme numérique que vos données ne représentent pas comme numérique (les espaces ne sont pas numériques). Donc: vérifiez la définition de votre table et comparez-la avec vos instructions d'entrée.
APC
10
Pourquoi les gens voteraient-ils pour cette question? Pour les personnes qui ne connaissent pas les bases de données, c'est une erreur étrange. Je peux voir comment inclure les valeurs avec des guillemets peut donner l'impression que c'est une chaîne. Cela dépend simplement de la configuration de la base de données. Tout cela peut être des chaînes ou des nombres qui dépendent simplement des champs. C'était peut-être une erreur lors de la création de la base de données.
sisharp
Un exemple de la situation ci-dessus: insérer dans table_1 (rollNumber) les valeurs ('123'); où rollNumber est une colonne de type "nombre".
Ishani Gupta
3
«De retour à douze heures, j'ai sorti un livre de l'étagère et j'ai répondu à une question d'Oracle. Chez 'Stack, je suis toujours adepte, avec des connaissances que j'ai gardées, mais je n'ai toujours pas d' acceptation. "
Aaron

Réponses:

121

Une erreur ORA-01722 se produit lorsqu'une tentative est effectuée pour convertir une chaîne de caractères en un nombre et que la chaîne ne peut pas être convertie en un nombre.

Sans voir la définition de votre table, il semble que vous essayez de convertir la séquence numérique à la fin de votre liste de valeurs en un nombre, et les espaces qui la délimitent génèrent cette erreur. Mais sur la base des informations que vous nous avez fournies, cela peut se produire sur n'importe quel domaine (autre que le premier).

Aaron
la source
2
Notez également que remplir manuellement un champ avec "(null)" vous donnera cette erreur. Si la valeur par défaut est nulle et que vous ne la complétez pas, elle se complétera automatiquement avec (null) mais ce n'est pas la même chose lorsque vous la tapez.
bogdan.rusu
Eh, "la chaîne ne peut pas être convertie en nombre" - Ce n'est pas le point. La chaîne PEUT être convertie en nombre. Le point ici est la conversion opposée d'un nombre en colonne String, mais Oracle ne le fait pas automatiquement: vous devez en faire une String vous-même, en marquant la valeur explicitement dans votre expression SQL, pour l'entourer de '' OU "" .
Franta
25

Supposons que le numéro de téléphone soit défini comme NUMBERalors les espaces ne peuvent pas être convertis en nombre:

create table telephone_number (tel_number number);
insert into telephone_number values ('0419 853 694');

Ce qui précède vous donne un

ORA-01722: numéro invalide

hol
la source
16

Voici une façon de le résoudre. Supprimez les caractères non numériques, puis convertissez-les en nombre.

cast(regexp_replace('0419 853 694', '[^0-9]+', '') as number)
gmlacrosse
la source
6
Cela supprimerait le 0 principal.
Joe C
2
cela va à l'OP d'origine - la colonne de votre table ne peut pas être de type "nombre" si vous voulez stocker des valeurs comme '0419 853 694' car le nombre ne peut pas avoir de zéros non significatifs. dans mon cas cependant c'est exactement ce dont j'avais besoin, ty gmlacrosse!
hipokito
10

Comme cette erreur survient lorsque vous essayez d'insérer une valeur non numérique dans une colonne numérique de db, il semble que votre dernier champ soit numérique et que vous essayez de l'envoyer sous forme de chaîne dans la base de données. vérifiez votre dernière valeur.

Pigiste
la source
8

Eh bien, cela peut aussi être:

SELECT t.col1, t.col2, ('test' + t.col3) as test_col3 
FROM table t;

où pour la concaténation dans oracle est utilisé l'opérateur ||non +.

Dans ce cas, vous obtenez: ORA-01722: invalid number ...

Lazar Lazarov
la source
1
C'en est une bonne. Un autre destin empoisonné peut être celui-ci. Vous avez commenté un champ dans une liste de champs SELECT comme - t.fieldname. Plus tard, vous avez l'intention de supprimer ce commentaire de début de ligne, mais un caractère commenté est laissé par accident. Il y a donc: - t.fieldname. Cela m'est arrivé, alors que je travaillais sur une très grosse requête, où je dois commenter / décommenter des centaines de colonnes, tout en réorganisant la bête.
olippuner
8

Ceci est dû au fait:

Vous avez exécuté une instruction SQL qui a tenté de convertir une chaîne en un nombre, mais sans succès.

Comme expliqué dans:

Pour résoudre cette erreur:

Seuls les champs numériques ou les champs de caractères contenant des valeurs numériques peuvent être utilisés dans les opérations arithmétiques. Assurez-vous que toutes les expressions sont évaluées en nombres.

Mahmoud Gamal
la source
4

Oracle effectue une conversion automatique String2number , pour les valeurs de colonne String ! Cependant, pour les comparaisons textuelles en SQL, l'entrée doit être délimitée comme une chaîne de manière explicite: La conversion opposée number2String n'est pas effectuée automatiquement, pas au niveau de la requête SQL.

J'ai eu cette requête:

select max(acc_num) from ACCOUNTS where acc_num between 1001000 and 1001999;

Celui-là posait un problème: Error: ORA-01722: invalid number

Je viens d'entourer les valeurs "numériques" , pour en faire des 'chaînes' , en les délimitant simplement :

select max(acc_num) from ACCOUNTS where acc_num between '1001000' and '1001999';

... et voilà: il renvoie le résultat attendu.

edit: Et en effet: le col acc_numdans ma table est défini comme String. Bien que non numérique, le a invalid numberété signalé. Et la délimitation explicite des numéros de chaîne a résolu le problème.

D'autre part, Oracle peut traiter les chaînes comme des nombres. Ainsi, les opérations / fonctions numériques peuvent être appliquées sur les chaînes, et ces requêtes fonctionnent:

sélectionnez max (string_column) dans TABLE;

sélectionnez string_column dans TABLE où string_column entre '2' et 'z';

sélectionnez string_column dans TABLE où string_column > '1';

sélectionnez string_column dans TABLE où string_column <= 'b';

Franta
la source
J'ai rencontré une situation similaire. ora-01722 numéro-invalide a été déclenché à une instruction select, pas une instruction insert. J'ai vérifié la définition de la table et j'ai trouvé que la colonne était un varchar au lieu d'un nombre, j'ai donc ajouté des guillemets simples autour du numéro
Newton fan 01
2

Dans mon cas, l'erreur de conversion était dans l' index fonctionnel , que j'avais créé pour la table.

Les données insérées étaient correctes. Il m'a fallu un certain temps pour comprendre que l'erreur réelle provenait de l'index de buggy.

Ce serait bien, si Oracle avait pu donner un message d'erreur plus précis dans ce cas.

Je prends
la source
1

Si vous faites une insert into...select * from...déclaration, il est également facile d'obtenir l'erreur «Nombre invalide».

Disons que vous avez une table appelée FUND_ACCOUNTqui a deux colonnes:

AID_YEAR  char(4)
OFFICE_ID char(5)

Et disons que vous souhaitez modifier le OFFICE_ID pour qu'il soit numérique, mais qu'il existe des lignes existantes dans la table, et pire encore, certaines de ces lignes ont une valeur OFFICE_ID de '' (vide). Dans Oracle, vous ne pouvez pas modifier le type de données d'une colonne si la table contient des données, et il faut un peu de ruse pour convertir un «» en un 0. Alors, voici comment procéder:

  1. Créez une table en double: CREATE TABLE FUND_ACCOUNT2 AS SELECT * FROM FUND_ACCOUNT;
  2. Supprimez toutes les lignes de la table d'origine: DELETE FROM FUND_ACCOUNT;
  3. Lorsqu'il n'y a pas de données dans la table d'origine, modifiez le type de données de sa colonne OFFICE_ID: ALTER TABLE FUND_ACCOUNT MODIFY (OFFICE_ID number);

  4. Mais alors voici la partie délicate. Étant donné que certaines lignes contiennent des valeurs OFFICE_ID vides, si vous effectuez une opération simple INSERT INTO FUND_ACCOUNT SELECT * FROM FUND_ACCOUNT2, vous obtiendrez l'erreur «ORA-01722 Numéro invalide». Afin de convertir les OFFICE_ID (vides) en 0, votre instruction d'insertion devra ressembler à ceci:

INSERT INTO FUND_ACCOUNT (AID_YEAR, OFFICE_ID) SELECT AID_YEAR, decode(OFFICE_ID,' ',0,OFFICE_ID) FROM FUND_ACCOUNT2;

Frank Staheli
la source
Ceci est un exemple très compliqué d'un cas où l'erreur pourrait se produire + une explication sur la façon de résoudre ce cas spécifique, qui peut ne pas s'appliquer du tout.
Jan Doggen
0

Cela m'est arrivé aussi, mais le problème était en fait différent: le codage des fichiers .

Le fichier était correct, mais le codage du fichier était incorrect. Il a été généré par l'utilitaire d'exportation de SQL Server et je l'ai enregistré sous Unicode.

Le fichier lui-même avait l'air bien dans l'éditeur de texte, mais lorsque j'ai ouvert le *.badfichier généré par le chargeur SQL * avec les lignes rejetées, j'ai vu qu'il y avait de mauvais caractères entre chaque caractère original. Puis j'ai réfléchi à l'encodage.

J'ai ouvert le fichier original avec Notepad ++ et je l'ai converti en ANSI, et tout s'est chargé correctement.

ciencia
la source
-1

L'erreur ORA-01722 est assez simple. Selon Tom Kyte :

Nous avons tenté de convertir explicitement ou implicitement une chaîne de caractères en nombre et cela échoue.

Cependant, où se situe le problème n'est souvent pas apparent au début. Cette page m'a aidé à dépanner, trouver et résoudre mon problème. Astuce: recherchez les endroits où vous convertissez explicitement ou implicitement une chaîne en nombre. (J'avais NVL(number_field, 'string')dans mon code.)

Baodad
la source
-1

essayez ceci aussi, lorsque vous avez une erreur de numéro invalide

Dans ce a.emplid est number et b.emplid est un varchar2 donc si vous devez convertir l'un des côtés

où to_char (a.emplid) = b.emplid

Geai
la source
-4

Vous pouvez toujours utiliser la fonction TO_NUMBER () afin de supprimer cette erreur. Cela peut être inclus comme INSERT INTO employés phone_number valeurs (TO_NUMBER ('0419 853 694');

Harshit Gupta
la source