2011-07-14 22 views
3

カーソルを作成して実際のデータを選択し、生の値と値を数値に変換して出力します。アプリケーションで無効な数値エラーがスローされることがあります。以下は私のテスト(select文を含まない)のコードと出力です。私が受け取るPlsql関数の質問

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

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

...生の答えが '< 3' である。ここ

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

が出力されます。

アプリケーションによって使用される実際のコードがそうのように見えることに注意してください:

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

と動的SQL文字列でのWHERE句の一部です。私は関数を取得していたので、decodeステートメントをcaseステートメントに置き換えました。疑似列の 'DECODE'は、SQLステートメントのエラー内で使用される可能性があります。

は最後に、私の質問はこれらです:

  1. はなぜ記号未満と
  2. ORA-1722とORA-間(素人の面で)違いは何を交換する翻訳機能ではありません06502エラー?

編集:私は、もはや06502エラーを受信しない、

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

を:私は、私はcase文を変更したときに気づきました。私が投稿した元のコード行を見てから、無効な数値エラーを引き起こしている可能性のあることについての提案がありますか?(翻訳される文字列には文字が存在しないと仮定しています)あるいは、オリジナルの開発者が何をしようとしていたかを達成する良い方法がありますか?ここで

は、変数の宣言されています。それはチャンスを得ていないので、

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

関連するエラーのタグ情報は#2に関するいくつかの情報を提供するかもしれません。ORA-06502 –

+0

私の編集内容を参照して、変数宣言を見たいと思います。私はタグをチェックアウトします。ありがとう! –

答えて

5

まず、TRANSLATEは「<」記号を交換していません。 CASEステートメントは、1つの条件の数値ともう1つの条件のcharを評価しています。あなたのケースの出力が一致している場合、私はあなたのエラーが離れて行くと信じて:

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

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:

REGEXP_REPLACEのご利用にはよさそうだが、私はありましたかこれをコーディングすると、読みやすくするためにDECODEの代わりにCASEを使用します。

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

これを行うより良い方法があれば教えてください:TO_NUMBER(REPLACE(TRANSLATE(INSTR(hra_ans.answer_text、 '。'、1,2)、0、UPPER(hra_ans.answer_text)、0) 'ABCDEFGHIJKLMNOPQURSTWVXYZ + <>:'、 '')、 ''、 ''))?私は翻訳を削除してto_number(TRIM(Regexp_replace)(デコード(INSTR(hra_ans.answer_text、 '。'、1,2)、0、UPPER(hra_ans.answer_text)、0)、 '[^ 0- 9.] '、' '))。どのような考えですか? –

+0

私の編集した答えを見てください。 – DCookie