Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/10/2007, 12h26   #1
Invité de passage
 
Inscription : octobre 2007
Messages : 4
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 4
Points : 1
Points : 1
Par défaut Erreur numérique ORA-06502

Bonjour,

C'est mon premier post sur les forums de developpez.com, que je fréquente depuis quelques années. Aujourd'hui j'ai un problème sur une procédure PL/SQL sur base oracle, j'éspère que quelqu'un pourra m'aider !

Il s'agit de lire deux valeurs dans un fichier csv et de les stocker dans une table. J'utilise pour cela deux variables (Variable_1 et Variable_2).

Voilà le message d'erreur qui apparait lors de l'execution:
ORA-06502: erreur numérique ou erreur sur une valeur: erreur de conversion des caractères en chiffres.

Et voilà mon code:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
 
CREATE OR REPLACE PROCEDURE MA_PROCEDURE IS
 
/* Déclaration des variables */
fichier utl_file.file_type; 
buffer VARCHAR2 (1024);
pos1 INT := 1; 
pos2 INT := 1; 
Variable_1 TABLE_1.COLONNE_1%TYPE;
VARIABLE_2 TABLE_1.COLONNE_2%TYPE;
ESL TABLE_1.COLONNE_2%TYPE;
ESF TABLE_1.COLONNE_2%TYPE;
EST TABLE_1.COLONNE_2%TYPE;
premiereligne INT :=1;
 
/* Début de procédure */
BEGIN
 
/* Ouverture du fichier source */
   fichier := utl_file.fopen ('chemin','fichier.csv','r');
 
LOOP
BEGIN
 
/* Lecture */
   IF premiereligne = 0 THEN --on ne veut pas lire la premiere ligne du fichier qui contient les noms de colonnes
   	  pos1 := 1;
   	  pos2 := 1;
   	  utl_file.get_line (FILE => fichier ,buffer => buffer);
 
   	  pos1 := INSTR (buffer, ';', 1, 3)+1;
   	  pos2 := INSTR (buffer, ';', 1, 4);
   	  Variable_1 := SUBSTR(buffer, pos1, pos2-pos1);
 
 
   	  pos1 := INSTR (buffer, ';', 1, 6)+1;
   	  pos2 := INSTR (buffer, ';', 1, 7);
   	  VARIABLE_2 := SUBSTR(buffer, pos1, pos2-pos1);   
 
/* Update */
   	  IF Variable_1 <> "ESL" AND Variable_1 <> "ESF" THEN
   	  	 UPDATE TABLE_1 SET COLONNE_2 = VARIABLE_2
   	  	 WHERE COLONNE_1 = Variable_1;
      ELSE
   	  	 IF Variable_1 = "ESL" THEN ESL := VARIABLE_2;
	  	 END IF;
	  	 IF Variable_1 = "ESF" THEN ESF :=VARIABLE_2;
	  	 END IF;
   	  END IF;
   ELSE
   premiereligne :=0;
   END IF;
END;
END LOOP;
 
EST := ESL + ESF;
UPDATE TABLE_1 SET COLONNE_2 = EST
WHERE COLONNE_1 = "EST";
 
utl_file.fclose(fichier);
COMMIT;
 
   EXCEPTION
     WHEN NO_DATA_FOUND THEN
       NULL;
     WHEN OTHERS THEN
       -- Consider logging the error and then re-raise
       RAISE;
END MA_PROCEDURE;
/
Lors de débuggage, la procédure lit la première ligne du fichier csv, et donne une valeur correcte à la Variable_1, puis à la Variable_2. Ce n'est qu'ensuite qu'apparait le message d'erreur.

TABLE_1.COLONNE_1 est du type VARCHAR2(15). Les valeurs lues dans le .csv ne dépassent pas les 3 caractères.
TABLE_1.COLONNE_2 est du type NUMBER(16,2). Les valeurs lues dans le fichier csv ne dépassent pas une longueur de 16 caractères, et sont des numériques à deux chiffres apres la virgule.


Quelqu'un sautait-il d'ou cette erreur peut venir? Merci d'avance !
GreekNotGeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 13h22   #2
Expert Confirmé
 
Homme
Chef de projet en SSII
Inscription : janvier 2004
Messages : 2 866
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : Conseil

Informations forums :
Inscription : janvier 2004
Messages : 2 866
Points : 3 448
Points : 3 448
Qu'as-tu dans variable_2 ?
=> vérifie que c'est bien une valeur numérique pour toutes les lignes.
__________________
Un problème sans solution est un problème mal posé

Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.
plaineR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 14h54   #3
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Je pense que tu as des problème dans ton code
  1. Ta boucle est infinie, il doit y avoir un test de sortie lorsque ton fichier est vide
  2. Ton test sur premiereligne = 0 amène à faire premiereligne=0 sans même faire un get_line pour zapper effectivement la première ligne
A mon avis, ton problème vient que tu ne sors pas du traitement quand tu as fini de lire ton fichier, donc tu alimentes tes zones avec NULL et forcément à la conversion, cela ne lui plait pas
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 15h19   #4
Invité de passage
 
Inscription : octobre 2007
Messages : 4
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 4
Points : 1
Points : 1
Merci de vos réponses .

plaineR, j'utilise TOAD, qui a un débugger laissant à désirer... Donc je suis la progression de mes deux variables, en utilisant "break on value change": je lance l'execution, la premiere etape est que la variable_1 prends la valeur "AAA" lue dans le fichier (ce qui signifie que ma bidouille pour ne pas lire la premiere ligne du fichier fonctionne, Loyd1974.), puis je reclique et la variable_2 prend la valeur 607094,53. Et c'est ensuite qu'apparait l'erreur...
Variable_2 est donc un numérique ! Et c'est le seul endroit du code ou je lui attribue une valeur...

Loyd1974, ton conseil parait logique, mais j'ai codé cette procédure à l'image d'une procédure existante qui fonctionne. Et apparemment, LOOP passe a la prochaine ligne du csv automatiquement, et n'a besoin d'aucune condition de sortie. En tant que programmeur objet, je dois dire que ca me parait bizarre a moi aussi. Mais de toute facon, le problème survient avant le début du deuxième passage dans la boucle...
GreekNotGeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 15h26   #5
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Citation:
Envoyé par GreekNotGeek Voir le message
la variable_2 prend la valeur 607094,53
Vérifie que le séparateur décimal dans ton fichier correspond bien à celui de ta base de données. Si c'est le point et que tu utilises une virgule, alors la cause est là
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 15h34   #6
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Citation:
Envoyé par GreekNotGeek Voir le message
Loyd1974, ton conseil parait logique, mais j'ai codé cette procédure à l'image d'une procédure existante qui fonctionne. Et apparemment, LOOP passe a la prochaine ligne du csv automatiquement, et n'a besoin d'aucune condition de sortie. En tant que programmeur objet, je dois dire que ca me parait bizarre a moi aussi. Mais de toute facon, le problème survient avant le début du deuxième passage dans la boucle...
Effectivement, ca marche, j'avais oublié que la procédure get_line renvoyait une exception no_data_found quand on arrive à la fin du fichier.
Par contre, toute cette partie de code ne sera jamais exécuté:
Code :
1
2
3
4
5
6
EST := ESL + ESF;
UPDATE TABLE_1 SET COLONNE_2 = EST
WHERE COLONNE_1 = "EST";
 
utl_file.fclose(fichier);
COMMIT;
car elles se situent entre la boucle et l'exception, alors qu'il faudrait qu'elles soient après le exception ... end

Pour être plus propre, ta structure devrait être
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
DECLARE 
...
BEGIN
...
   BEGIN
      LOOP
          ...
      END LOOP
   EXCEPTION
      WHEN NO_DATA_FOUND THEN 
           NULL;
      WHEN OTHERS THEN
           RAISE;
    END;
....
EXCEPTION
    ...
END;
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 15h39   #7
Expert Confirmé
 
Homme
Chef de projet en SSII
Inscription : janvier 2004
Messages : 2 866
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : Conseil

Informations forums :
Inscription : janvier 2004
Messages : 2 866
Points : 3 448
Points : 3 448
Citation:
Envoyé par GreekNotGeek Voir le message
Et apparemment, LOOP passe a la prochaine ligne du csv automatiquement, et n'a besoin d'aucune condition de sortie. En tant que programmeur objet, je dois dire que ca me parait bizarre a moi aussi.
Il sort de la boucle car une exception no_data_found est levée à la fin du fichier.

Ton séparateur de décimale est-il la virgule ?
__________________
Un problème sans solution est un problème mal posé

Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.
plaineR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 16h16   #8
Invité de passage
 
Inscription : octobre 2007
Messages : 4
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 4
Points : 1
Points : 1
Ma base de données utilise bien la virgule (mais j'avais essayé avec des points, aussi, et l'erreur était la même).

C'est vrai, le code après le END LOOP n'aurait jamais été executé, merci. Mais cela ne règle pas mon problème é_è . Je continue de chercher...
GreekNotGeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 16h45   #9
Expert Confirmé
 
Homme
Chef de projet en SSII
Inscription : janvier 2004
Messages : 2 866
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : Conseil

Informations forums :
Inscription : janvier 2004
Messages : 2 866
Points : 3 448
Points : 3 448
As-tu essayé de faire l'update sous toad ou sous SQL*Plus avec la valeur que tu as dan variable_2 ?

As-tu essayé d'exécuter ta procédure sous SQL*Plus?
__________________
Un problème sans solution est un problème mal posé

Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.
plaineR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 17h23   #10
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Dès fois, il faudrait que j'apprenne à lire, tu dis que ta variable_2 vaut 6...,.. et que l'erreur vient après.
Si ta variable est initialisée, c'est que le traitement a été bon pour cette ligne, et vu les types que tu utilises pour tes variable, il n'y a pas de raison que l'update ne se fasse pas. Cela plante certainement sur la ligne d'après en fait.

En cas, tu peux rajouter des dbms_output pour débugger, cela marchera mieux que le débugger de TOAD
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2007, 17h53   #11
Invité de passage
 
Inscription : octobre 2007
Messages : 4
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 4
Points : 1
Points : 1
J'ai enfin trouvé la solution !

Mais alors celle là, dans le genre erreur à la con, elle est belle... :
J'utilisais des guillemets à la place d'apostrophes (exemple à la ligne suivante):

Code :
 IF Variable_1 <> "ESL" AND Variable_1 <> "ESF" THEN
Je vous remercie tous les deux pour votre aide, et je suis désolé de vous avoir dérangé pour une erreur aussi naze...

A la prochaine pour de nouvelles mésaventures !
GreekNotGeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h01.


 
 
 
 
Partenaires

Hébergement Web