• ベストアンサー

PL/SQLカーソルの2重FORループができません

こんにちは。 PL/SQLで下記のようなFORループを 2重3重に処理することはできないのでしょうか? コンパイル時に PLS-00103: 記号"END"が見つかりました と、内ループの"END"に対して起こられてしまいます。 お分かりになる方、よろしくお願いします。 … <<L_OUT>> FOR data_a IN csr_a LOOP  … <<L_IN>> FOR data_b IN csr_b LOOP  END LOOP L_IN;  … END LOOP L_OUT; …

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

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

  • ベストアンサー
回答No.3

カーソルのOPEN/CLOSEを明示するなら、問題はないと思います。 しかしながら、csr_a,csr_bを結合した1つのカーソルの 読み出しに変えた方が、より効率的かと思います。

pink_tomato
質問者

お礼

ご回答有難うございました。 問題点はほかにあったようで、 いろいろと修正しているうちに、問題は解決しました。

その他の回答 (3)

回答No.4

こんにちは。 LOOP文のネストは問題ありませんよ。 全体をコピペして載せて頂いた方がいいかと思いますが・・・? (^^ゞ

pink_tomato
質問者

お礼

ご回答有難うございました。 問題点はほかにあったようで、 いろいろと修正しているうちに、問題は解決しました。

  • cucsna
  • ベストアンサー率23% (12/51)
回答No.2

半分くらい、トンチンカンなことを書くと思いますが、ご容赦ください。 可能性として、 ・ENDが全角文字になっている ・ENDの直前の文に「;」がついていない ・必要ないENDがどこかに存在する ということを考えました。 全く確認などしていませんし、多分違うと思いますが、 いろいろ考える選択肢があった方がいいと思って書き込みました。 ロジック的には、ループの中で、さらにループを作っても問題はないと思います。(多分)

pink_tomato
質問者

お礼

ご回答有難うございました。 問題点はほかにあったようで、 いろいろと修正しているうちに、問題は解決しました。

回答No.1

文法云々より、考え方に問題があるような気がします。 外側のFORループのカーソルcsr_aで得られるレコード数分、 内側のFORループのカーソルcsr_bを読み直すということに なりますが、それがお望みなのですか?

pink_tomato
質問者

補足

csr_aで取得したレコードをcsr_bのwhere句の変数にしているので、ロジック的な問題はありません。 FORループの入れ子にではなくて、 外はFORループで、 内をOPEN/FETCH/CLOSEと通常の書き方にしたら うまくいくのでしょうか? (明日、会社へ行くまでちょっと試せないのですが・・・)

関連するQ&A

  • PL/SQLのカーソルについて

    PL/SQLのカーソルについて お世話になります。 Oracle11gで開発しています。 初心者です。 下記ストアドプロシージャの「zokuseisyutoku」で取得した 値(入数、重量、才数、ロケーション)を受けて、別のストアドプロシージャ 「Hyouji」の変数(irisuu、jyuryou、saisuu、lokesyon)に代入して得られた 内容をGridviewに表示させたいと思っています。 現在は、別々のストアドプロシージャなのですが、 一つに出来るものなら一つのストアドプロシージャにまとめたいの ですが、どなたかご親切な方、ご教授頂きたく宜しくお願い致します。        記 (1)ストアドプロシージャ1つ目 create or replace procedure zokuseisyutoku ( sItemClass in コード表.品番%type, out_val out pls_integer, out_cursor out sys_refcursor ) as begin if sItemClass is null then open out_cursor for select 入数, 重量, 才数, ロケーション from コード表 ; else open out_cursor for select 入数, 重量, 才数, ロケーション from コード表 where 品番 = sItemClass ; end if; out_val := 1; (2)ストアドプロシージャ2つ目 create or replace procedure Hyouji ( irisuu in 部材表.入数%type, jyuryou in 部材表.重量%type, saisuu in 部材表.才数%type, lokesyon in 部材表.ロケーション%type, out_val out pls_integer, out_cursor out sys_refcursor ) as begin open out_cursor for select b.資材名,b.色,b.種類,b.サイズ,b.棚番号 FROM 部材表 a,資材項目 b WHERE a.ID = b.資材ID AND a.入数 = irisuu AND a.重量 = jyuryou AND a.才数 = saisuu AND ロケーション = lokesyon ; out_val := 1; end; end;

  • PL SQL のループ

    あるセレクト文のパフォーマンスを測定するためにループで複数回実行し時間を測定したいのですが、select 変数 into をしないとコンパイルできず実行できません。 同じセレクト文を複数回実行し時間を測定するのに良い方法は無いでしょうか? CREATE OR REPLACE PROCEDURE test IS BEGIN DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); FOR i IN 1..100 LOOP SELECT a,b,c,d,e FROM tbl; END LOOP; DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); END;

  • PL/SQLで複数のFor文を解除したい

    PL/SQLでFor文を複数使用したデータ作成プログラムを作っています。 作成したデータが一定数に達したら全てのFor文を抜ける処理を 入れたいのですが、うまくいきません。 VBのExit Functionなどのように複数のFor文を一気に抜けるやり方は PL/SQLにはあるのでしょうか? ソース--------------------------------------------------------- (中略)    StrCnt := 1;    For i IN 1..3 LOOP       StrA := "あ"       For j IN 1..3 LOOP          StrB := "い"          For k IN 1..3 LOOP             StrC := "う"             outputStr := StrA || StrB || StrC ;             DBMS_OUTPUT.PUT_LINE (outputStr) ;             StrCnt := StrCnt + 1 ;                          --もしStrCntが5つ作成されればデータ作成を中断             IF StrCnt > 5 THEN                 ※ここで全てのループを解除したい             END IF;          EXIT LOOP;       EXIT LOOP;    EXIT LOOP; (後略) --------------------------------------------------------------- 環境は  【OS】Window2000 Pro  【Oracle】8.1.6       です。 Oracleを始めて一週間足らずの未熟者なので、ソース自体が違うかもしれませんが、 どなたかご存知の方、教えてください!

  • PL/SQLでFORの働き

    たびたびお世話になります。Oracle初心者で、PL/SQLを使ってすでに存在するレコードに順位の値を入れようと思っております。 DECLARE CURSOR カーソル IS SELECT * FROM tb ORDER BY 成績; n number:=0; BEGIN FOR r IN カーソル LOOP UPDATE tb SET 順位=n WHERE 成績=r.成績; n:=n+1; END LOOP; END; FORというもの自体がわからず恐縮です。これは正しく、カーソルで定義したORDER BYの順に動くと考えてもよいのでしょうか。上記を実際にやってみると、うまく順位が入るようなのですが、これはたまたまなのでしょうか。 お恥ずかしい限りですが、どうかよろしくお願いいたします。

  • 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 のように、列名を指定する以外方法はないのでしょうか? 初歩的な質問ですみませんが、よろしくおねがいします。

  • forループに慣れるには

    初めまして。 今資格を取ろうと思い独学でJavaを勉強してるんですが、 つまらない部分でつまずいています。 それは少々複雑なfor等のループです。 変数を追っていくうちにこんがらがってしまい、 変数の正しい値を見失ってしまいます。 例えば… Loop: for(int i = 0; i<5; i++) { for(int j =0; j<5; j++) { if(i==j) continue Loop; System.out.println("i = " +i+ "j = " +j); if(i > 3) break Loop; } } や、 int i,j; for(i = 0, j = 0; i<3;) { if(i++ == 2 || j++ == 2) break; } System.out.println(i); System.out.println(j); の様なループです。 試験範囲は大方勉強出来てるんですが まぬけな事にループがイマイチ理解出来てなくて(恥) 皆さんはどうやって慣れてこられましたか? つまらない質問ですが何か良いコツやアドバイスがあれば よろしくお願いします。

  • 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: 記号")"が見つかりました。 のエラーが出ます。

  • PL/SQLで

    set serveroutput on size 100000; declare wk_cnt integer; begin wk_cnt := 100; for wk_cnt in 1..10 loop … end loop; dbms_output.put_line(wk_cnt); end; / で、最後のwk_cntが10(11?)ではなく100になります。 何故でしょうか??

  • 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; /

  • 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回書きたくない) 初心者で、申し訳ないです。どうか、ご教授ください。