2011-07-14 2 views
3

J'ai créé un curseur pour sélectionner les données réelles et les parcourir pour produire la valeur brute et la valeur après la conversion en nombre. L'application génère parfois des erreurs de nombre non valides. Ci-dessous, mon code de test (sans inclure le code de sélection) et la sortie.PlSql Traduire la question de la fonction

LOOP 
    FETCH myCursor into v_answer; 
    EXIT WHEN myCursor%notfound; 

    DBMS_OUTPUT.PUT_LINE('Raw answer: ' || v_answer); 

    v_instr := INSTR(v_answer, '.',1 , 2) ; 
    v_number := TO_NUMBER(REPLACE(TRANSLATE (CASE v_instr 
              WHEN 0 THEN UPPER(v_answer) 
              ELSE 0 
              END,'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ','')); 

    DBMS_output.put_line('As number: ' || v_number); 

Voici la sortie:

Raw answer: 4 
As number: 4 
Raw answer: 3 
As number: 3 
Raw answer: 1.00 
As number: 1 
Raw answer: <3 

Je reçois:

PL/SQL: numeric or value error: character to number conversion error

... quand la réponse Raw est '< 3'.

S'il vous plaît noter que le code réel utilisé par l'application ressemble à ceci:

AND TO_NUMBER(REPLACE(TRANSLATE (decode(INSTR(hra_ans.answer_text, '.',1 , 2), 0 , UPPER(hra_ans.answer_text) , 0),'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ','')) 

et fait partie de la clause where dans une chaîne SQL dynamique. J'ai remplacé l'instruction de décodage par l'instruction case car j'obtenais une fonction ou une pseudo-colonne "DECODE" qui peut être utilisée dans une erreur d'instruction SQL uniquement.

Enfin, mes questions sont les suivantes:

  1. Pourquoi pas la fonction traduire en remplaçant le signe inférieur et
  2. Quelle est la différence (en termes simples) entre les ORA-1722 et Ora- 06502 erreurs?

EDIT: J'ai remarqué que lorsque je change la déclaration de cas:

CASE v_instr 
               WHEN 0 THEN UPPER(v_answer) 
               ELSE '0' 

,

Je ne reçois l'erreur 06502. En regardant la ligne de code d'origine que j'ai posté, y a-t-il des suggestions quant à ce qui peut causer l'erreur de nombre invalide (en supposant qu'aucun caractère n'existe dans la chaîne à traduire ne sont pas pris en compte)? Ou, y a-t-il une meilleure façon d'accomplir ce que le développeur original essayait de faire?

Voici les déclarations de variables:

v_answer varchar2(2000); 
v_number number; 
v_instr number; 
+0

Les informations sur les tags pour les erreurs associées peuvent fournir des informations sur votre # 2.Je voudrais voir la déclaration de la variable, basée sur ce que je lis pour ORA-06502 –

+0

Voir ma modification. Je vais vérifier les tags. Merci! –

Répondre

5

D'abord, le TRADUIRE ne remplace pas le symbole « < » parce qu'il ne se la chance. L'instruction CASE évalue un nombre dans une condition et un caractère dans l'autre. Si la sortie de votre CASE est conforme, je crois que vos erreurs disparaissent:

v_number := TO_NUMBER(REPLACE(TRANSLATE (CASE TO_CHAR(v_instr) 
              WHEN '0' THEN UPPER(v_answer) 
              ELSE '0' 
              END,'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ','')); 

De this post on asktom.com:

ORA-1722 is Invalid number. We've attempted to either explicity or implicitly convert a character string to a number and it is failing.

This can happen for a number of reasons. It generally happens in SQL only (during a query) not in plsql (plsql throws a different exception for this error).

EDIT:

Votre utilisation de regexp_replace semble bon, mais si je codant cela, j'utiliserais CAS au lieu de DECODE juste parce que je pense qu'il est plus facile à lire:

v_number := CASE WHEN INSTR(v_answer, '.',1 , 2) = 0 THEN -- has 0 or 1 period 
        TO_NUMER(REGEXP_REPLACE(v_answer,'[^0-9.]','')) 
       ELSE 0 -- has more than one period 
      END; 
+0

Pouvez-vous me dire s'il y a une meilleure façon d'accomplir ceci: TO_NUMBER (REMPLACER (TRADUIRE (décoder (INSTR (hra_ans.answer_text, '.', 1, 2), 0, UPPER (hra_ans.answer_text), 0), 'ABCDEFGHIJKLMNOPQURSTWVXYZ + <>:', ''), '', ''))? Je pense que supprimer le Translate et utiliser to_number (TRIM (Regexp_replace (décoder (INSTR (hra_ans.answer_text, '.', 1, 2), 0, UPPER (hra_ans.answer_text), 0), '[^ 0- 9.] ',' ')). Des pensées? –

+0

Voir ma réponse modifiée. – DCookie