• ベストアンサー

ORA-06502のエラー

以下のPL/SQLを実行すると、ORA-06502:数値または値のエラーとでます。途中までは、INSERTできるのですが、IF文の180個目くらいでエラーになります。そのあたりをCur1の宣言時にWhereで指定するとうまくいきます。 DECLARE CURSOR Cur1 IS SELECT MOJI FROM A_TBL ; CNT NUMBER(10); KAKKO_FL NUMBER(1); BEGIN CNT := 0; KAKKO_FL :=0; FOR Cur_Rec1 IN Cur1 LOOP FOR S IN 1 .. LENGTH(Cur_Rec1.MOJI) LOOP IF(ASCII(SUBSTR(Cur_Rec1.MOJI,S,1)) = 33129) THEN /*33129は'('*/ EXECUTE IMMEDIATE ' INSERT INTO EDD.test1116 VALUES( ''' || Cur_Rec1.MOJI || ''' ) '; END IF; END LOOP; END LOOP; END; なにがなんだか、さっぱりわからないので、どうか、ご教授ください。

  • Oracle
  • 回答数5
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
  • MZ-80B
  • ベストアンサー率56% (46/81)
回答No.2

もしや Cur_Rec1.MOJIが NULLになることはありませんか? Cur_Rec1.MOJI が NULLですと、それを引数にする ほぼすべての関数が NULLを返しますから、現在のコードではおかしな動きになります。 各所に NVL関数を使ってみてください。

pyontanrie
質問者

補足

NVLを使ってもだめでした。あたりをつけているレコードは、そのレコードだけをINSERTすると、うまくいんですよねえ。もう少し、アドバイスください。お手数をおかけしますが、どうかお願いします。

その他の回答 (4)

  • 7colors
  • ベストアンサー率25% (29/114)
回答No.5

EXCEPTION で VALUE_ERROR を拾ってDBMS_OUTPUTで 行を特定 そっから値の問題解決につなげては?

pyontanrie
質問者

お礼

みなさま、お返事ありがとうございました。原因は、やはり、NULLの問題でした。例に書いたより、もっと複雑なSQLで、アドバイスどおりNVLにした項目が間違っていました。怪しい項目をNVLすると、うまくいきました。本当にありがとうございます。トレースして、よくわかりました。

  • masusun
  • ベストアンサー率15% (44/285)
回答No.4

ん? '('を含む場合のみ別処理ですよね。 だったらそれが何レコード目かは「あたり」じゃなくて「特定」することは簡単ですよね。 No.3の方もおっしゃってますがトレースしてみれば早いかと。 EDDに挿入しようとしている実際の値を見ないことには解決も難しいと思います。 ためしにEDD.test1116、A_TBL.MOJIがvarchar2だったらどうなりますか?

pyontanrie
質問者

お礼

お返事ありがとうございました。レコード特定をヒントに原因がわかりました。上記に理由を書きます。

  • Senna_FF
  • ベストアンサー率45% (153/334)
回答No.3

>あたりをつけているレコードは ではなく、特定してください!! dbms_outputパッケージ等を使用して、A_TBL.MOJIの内容をトレースしてください。 その値をみればすぐわかると思いますが・・・

pyontanrie
質問者

お礼

お返事ありがとうございました。原因がわかりました。上記に書きます。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

ORA-06502: PL/SQL: 数値または値のエラー: 数値の精度が大きすぎます。が発生しました '<MOJIの内容>' をInsertしたいのですね。 なので SELECT MOJI FROM A_TBL のMOJIと INSERT INTO EDD.test1116 の精度は合っていますか? +2のサイズが必要ですよ。

pyontanrie
質問者

補足

MOJI CHAR(9)で、test1116のMOJIは、CHAR(11)にしましたが、同じエラーがでます。 申し訳ありませんが、もう少しアドバイスをお願いします。

関連するQ&A

  • SQL GO TOするには?

    SELECTしたものを飛ばしてからINSERTしたいのですが、 どうしたら良いですか? CURSOR A is  SELECT~~~ BEGIN  FOR rec IN cur_z LOOP   項目追加(Arec);  END LOOP; END; PROCEDURE 項目追加(rec) IS ←ここでエラー BEGIN    INSERT~~~~ END 項目追加; としてあるのですが、 PLS-00103: 記号"PROCEDURE"が見つかりました。 PLS-00103: 記号")"が見つかりました。 のエラーが出ます。

  • SQL文でどこが悪いのか教えて下さい

    初心者ですが教えて下さい。 表Aと表Bで表Aに含まれていないものを表Cに入れたいのですが、下記のやり方では表Aのものしか入れることができません。 どこが悪いのか教えて下さい。 ・コードは複雑なため、簡略化しています。UNIONは使わない方向で。 CREATE OR REPLACE PROCEDURE SAMPLE IS CURSOR SELLINE1 IS SELECT * FROM A ORDER BY KEY1,KEY2; CURSOR SELLINE2 IS SELECT * FROM B ORDER BY KEY1,KEY2; CNT1 NUMBER; CNT2 NUMBER; BEGIN SELECT COUNT(*) INTO CNT1 FROM C; IF CNT1 = 0 THEN FOR SELREC IN SELLINE1 LOOP INSERT INTO C VALUES (KEY1,KEY2,値);COMMIT; END LOOP; FOR SELREC IN SELLINE2 LOOP SELECT COUNT(*) INTO CNT2 FROM C WHERE (KEY1 = SELREC.KEY1) AND (KEY2 = SELREC.KEY2); IF CHK_CNT2 = 0 THEN INSERT INTO C VALUES (KEY1,KEY2,値);COMMIT; END IF; END LOOP; END IF; END; /

  • PL/SQLにてカーソル名を変数に

    PL/SQLにて、カーソル名を変数にしたいのですが、どうすればよいのでしょうか? 具体的には以下のとおりです。 DECLARE CURSOR Cur1 IS SELECT K1,K2 FROM EMP; BEGIN FOR Cur_Rec1 IN Cur1     Cur_Rec1.K1 DBMS_OUTPUT.PUT_LINE(Cur_Rec1.K1); ★ END LOOP; END; ★の部分の「Cur_Rec1.K1」を「Cur_Rec1.K2」として、置き換えて使用したいのです。(2回書きたくない) 初心者で、申し訳ないです。どうか、ご教授ください。

  • PL/SQLで変数へ値の代入

    PROCEDURE TEST(PI_ABC IN A_TABLE.A_CODE%TYPE) IS CURSOR CUR IS SELECT A_CODE FROM A_TABLE; BEGIN --抽出したデータを代入 FOR REC_CUR IN CUR LOOP PI_ABC := REC_CUR.A_CODE; END LOOP; 上記のコードを実行すると ORA-06502:数値または値のエラー PL/SQL: 文字列バッファが小さすぎます。 とエラーが出ます。 このプロシージャを呼び出す時にも同じテーブル同じ項目を渡しています。 同パッケージ内で同じ事をやっているのに特定のプロシージャだけ 上記のエラーが出てしまいます。 環境:Windows2003Server oracle9i

  • PL/SQLでの参照

    PL/SQLで、複数データをLOOPで 読み込む処理を行います。 TYPE T_CHR IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; vc_data T_CHR; FOR cur_01 IN rec_01 LOOP vc_data(1) := rec_01.SHOHIN1 vc_data(2) := rec_01.SHOHIN2 vc_data(3) := rec_01.SHOHIN3 vc_data(4) := rec_01.SHOHIN4 ・・・・・ vc_data(50) := rec_01.SHOHIN50 END LOOP; 上記のような処理をしたいのですが、vc_dataに セットする処理を、Loopでできないですか? FOR n_count IN 1..50 LOOP vc_data(n_count) := rec_01(n_count); END LOOP; のようなかんじで。。。 今は50個羅列したままです。 でも、上のような処理は、エラーでした。 rec_01は、 rec_01.SHNNO1 のように、列名を指定する以外方法はないのでしょうか? 初歩的な質問ですみませんが、よろしくおねがいします。

  • カーソルで集合関数を使った場合のEXCEPTION

    PL/SQLの質問です。 declare でカーソルを宣言し、その中で集合関数を使用しています。(sum) CHAR型の項目に対して掛けるので、数値でないものが入っていた場合のために INVALID ERRORのEXCEPTIONをつけました。 BEGINE  FOR rec IN cur_test  LOOP   ----  END LOOP; EXCEPTION  WHEN INVALID_NUMBER THEN   ------ END; しかし、このやりかただと、一部のレコードでエラーがあっても、 全てのレコードがエラーと判断されてしまいます。 カーソルで集合関数エラーが発生したレコードのみEXCEPTIONで扱い、 それ以外のデータはきちんとチェックしたいのですが、 そのような方法はあるでしょうか? よろしくお願いします。

  • Insertの質問

    いつもお世話になっております。 Oracle11gとC#.NETで開発している初心者です。 ストアドプロシージャによるテーブルからテーブルへの インサートがうまくいかず悪戦苦闘しております。 下記の様な記述をしており、コンパイルは通ったのですが、 D売上見通台帳のIDをプライマリーキーにしており、 実際.NETで動かしてみると、一意制約違反でエラーとなって しまいます。 どなたかご親切な方ご教授頂きたく、 宜しくお願い申し上げます。       記 create or replace procedure dbInsert台帳追加 ( out_val out pls_integer ) as cursor cur is SELECT 注文主,受注NO,売上日,品番,品名,数量, 登録日時,登録者 FROM D売上台帳 WHERE 売上日 = TO_CHAR(sysdate,'YYYY/MM/DD') ; cur_rec cur%rowtype; begin open cur; loop fetch cur into cur_rec; exit when cur%notfound; INSERT INTO D売上見通台帳 ( ID,注文主,受注NO,売上日,品番,品名,数量, 登録日時,登録者,更新日時,更新者 ) VALUES ( seqD売上台帳ID.nextval,cur_rec.注文主,cur_rec.受注NO,cur_rec.品番,cur_rec.品名, cur_rec.数量,cur_rec.登録日時,cur_rec.登録者,cur_rec.更新日時,cur_rec.更新者 ) ; end loop; close cur; out_val := sql%rowcount; end;

  • カーソルについて

    カーソルってオープン時に該当データの全レコードセットを取得するんでしょうか?。 PL/SQLでVIEWのカーソルをオープンし、ループ処理を行っているんですが、処理速度からして1フェッチごとに毎回SELECT文を発行しているように見受けられます・・・。 ソースはこんな感じです↓。 declare cursor cur_tb_1 is select * from ビュー; begin for rec_tb_1 in cur_tb_1 loop ...処理いろいろ end loop; end; また、このようなケースの場合、VIEWのSELECT結果を一時テーブルにINSERTし、そのテーブルをSELECTするカーソルを使用するほうが 作法的によいのでしょうか?

  • PL/SQLについての質問です。

    PL/SQLについての質問です。 カーソルデータ(emp_rec(i))を、TABLE変数(emp_ins(i))に代入して、代入されたTABLE変数を使用して、DML処理を行うことは可能ですか? エラーを解読し対処を行っても、エラーが発生してしまいます。 どうか、ご教授お願いします。 下記を実行すると、下記エラーが発生します。 -実行結果------------------------------------ DECLARE * 行1でエラーが発生しました。: ORA-06502: PL/SQL: 数値または値のエラーが発生しました ORA-06512: 行127 -エラー番号解読----------------------------------------- ●エラー名: PL/ SQL: 数値または値のエラーstring が発生しました ●原因: 算術、数値、文字列、変換または制約エラーが発生しました。たとえば、NULL 値をNOT NULL で宣言した変数に割り当てようとした場合、または100 以上の整数をNUMBER( 2) で宣言した変数に割り当てようとした場合にこのエラーが発生します ●処置:値が制約違反をしないように、データ、操作方法または宣言方法を変更してください。 -ソース------------------------------------ DECLARE --カーソル定義 CURSOR emp_cur IS SELECT a,b,c FROM emp TYPE emptabtype IS TABLE OF emp%ROWTYPE INDEX BY PLS_INTEGER; emp_rec emptabtype; /* 処理対象データ格納変数 */ -- insert作業用 emp_ins emptabtype; ins_count NUMBER := 1; BEGIN /* empカーソルオープン・フェッチ・クローズ */ OPEN emp_cur; FETCH emp_cur BULK COLLECT INTO emp_rec; CLOSE emp_cur; /* (挿入)処理対象のデータを、処理対象データ格納変数に格納する。 */ FOR i IN emp_rec.FIRST..emp_rec.LAST LOOP --挿入するレコードを格納 emp_ins(ins_count) := emp_rec(i); ins_count := ins_count + 1; END LOOP; /* DML処理 */ -- 挿入する FOR count_ins IN emp_ins.FIRST..emp_ins.LAST LOOP INSERT INTO temp VALUES(emp_ins(count_ins).a ,emp_ins(count_ins).b ,emp_ins(count_ins).c); END LOOP; COMMIT; END; /

  • PLPGSQL レコードセットを列数で取得したい

    Postgresで関数(ストアドプロシージャ)を作成するのに PLPGSQLを使用しています。 レコードセットを取得し、1列目~40列目までを順次値を判定し、特定の値がある場合は、41列~80列のそれぞれ対応する(1列目なら41列目、13列目なら53列目…)列から数値を取得する動きを実現したいと考えています。 上記条件は下記プログラムで実現してますが、再帰処理で同じことが実現できないでしょうか? ※商品マスタを作成して、クエリを作成するのが当たり前と思いますが、よんどころのない事情でこのテーブル形式をを崩せません。(外部システムの汎用データから取り込むためです) ------------------- 以下現状のプログラム ------------------- declare rec record; int1 integer; begin int1:=0; for rec in select * from kudamonouriage where syainid=$1 and kppw=$2 loop if substr(rec.kate1,1,3)='りんご' then int1:=int1+rec.kingaku1; end if; if substr(rec.kate2,1,3)='りんごthen int1:=int1+rec.kingaku2; end if; if substr(rec.kate3,1,3)='りんご' then int1:=int1+rec.kingaku3; end if; … … if substr(rec.kate39,1,3)='りんご' then int1:=int1+rec.kingaku39; end if; if substr(rec.kate40,1,3)='りんご' then int1:=int1+rec.kingaku40; end if; end loop; return int1; end; ---------------- 以上現状のプログラム --------------------- これを ------------------- 希望するプログラム ------------------- declare rec record; int1 integer; begin int1:=0; for rec in select * from kudamonouriage where syainid=$1 and kppw=$2 loop for i 1..40 loop if substr(rec.(i),1,3)='りんご' then int1:=int1+rec.(40+i); end if; end loop; end loop; return int1; end; ---------------- 以上希望のプログラム --------------------- このようにしたいと思っています。 サイト上で色々と検索していますが、解決に至っていません。お力を貸していただけると大変助かります。宜しくお願いいたします。