• 締切済み

PLSQLの識別子エラー

下記PLSQLを実行した時に(sqlplus上で、@XXXX.SQLと実行) WCOUNT :=WCOUNT + 1; エラー PLS-00201: 識別子WCOUNTを宣言してください のエラーがでます 宣言をしているのですがわからず、お助けください また、他にもこのエラーを処置したあとに問題と なりそうな箇所があれば指摘お願いします -やろうとしてること (1)テーブルA を、男子を出席順に読み込んでその読み込んだ順番に 1から番号をふり、テーブルBへ新規追加する (2)テーブルAからテーブルBに新規追加していない女子を、出席順に読み込んで 1から番号をふり、テーブルBへ新規追加する (3)テーブルBのKEYは順番のみ (4)テーブルBのINSERT分は、今後機能追加する予定なのでNOT IN使用する -組んだPL/SQL(2つのINSETを1つのファイルに記述しています) DECLARE WCOUNT number; CURSOR カーソル IS SELECT 出席番号,名前,成績 FROM テーブルA  ORDER BY 出席番号; BEGIN FOR r IN カーソル LOOP INSERT INTO テーブルB (r.順番, r.名前,r.出席番号) VALUES (WCOUNT,r.名前); COMMIT; WCOUNT :=WCOUNT + 1; END LOO; / END; DECLARE CURSOR カーソル IS SELECT 出席番号,名前,成績 FROM テーブルA A WHERE A.出席番号 NOT IN (SELECT B.出席番号 FROM テーブルB B) ORDER BY 出席番号; BEGIN FOR r IN カーソル LOOP INSERT INTO テーブルB (順番, 名前) VALUES (WCOUNT,r.名前); COMMIT; WCOUNT :=WCOUNT + 1; END LOOP; / END;

  • Oracle
  • 回答数2
  • ありがとう数3

みんなの回答

回答No.2

タイプミスがありました。 一行目のVARですが・・ VAR WCOUNT NUMEBR => VAR WCOUNT NUMBER SQL*PLUS上なら、特別な作業を必要とせずに、バインド変数は使えるはずです。

回答No.1

投稿されたSQLは、明らかな転記ミスと思しき箇所があるので、 何が転記ミスで、何が本来の問題点なのか区別が付かないのですが・・ declare ~(a)~ begin ~(b)~ end; / declare ~(c)~ begin ~(d)~ end; / という一連のスクリプトの場合、(a)で定義した変数は、(b)で有効ですが、 別の無名ブロックである(d)では、利用できません。改めて(c)で定義する必要があります。 無名ブロック間で変数を共有する場合、declareで定義するPL/SQL変数ではなく、 バインド変数を使います。(SQL*PLUSのVARコマンド参照) --ここから VAR WCOUNT NUMEBR DECLARE CURSOR カーソル IS SELECT 出席番号,名前,成績 FROM テーブルA ORDER BY 出席番号; BEGIN FOR r IN カーソル LOOP INSERT INTO テーブルB (r.順番, r.名前,r.出席番号) VALUES (:WCOUNT,r.名前); COMMIT; :WCOUNT := :WCOUNT + 1; END LOOP; END; / DECLARE CURSOR カーソル IS SELECT 出席番号,名前,成績 FROM テーブルA A WHERE A.出席番号 NOT IN (SELECT B.出席番号 FROM テーブルB B) ORDER BY 出席番号; BEGIN FOR r IN カーソル LOOP INSERT INTO テーブルB (順番, 名前) VALUES (:WCOUNT,r.名前); COMMIT; :WCOUNT := :WCOUNT + 1; END LOOP; END; / --ここまで カーソルループの中で、コミットしてるのは、気になったのですが、そのままにしています。 また、スクリプトファイル中での空行は気をつけた方がいいですよ。

bancho_033
質問者

補足

返信ありがとうございます 早速訂正し、SQLplus上にて実行したところ SP2-0552: バインド変数”WCOUNT”が宣言されていません。 のエラーがでてしまいました バインド変数を利用するのに何か設定がいるのでしょうか

関連するQ&A

  • PLSQLについて

    いつもお世話になります。 オラクル初心者です。 宜しくお願い致します。 下記の様な、for~loopで、 tmpM商品単価(主キーなし)と言う一時表テーブルから M商品単価(主キーは「品番」)へインサートをする際、 tmpM商品単価には、「品番」フィールドにダブった品番 がある為、単価実行日を降順に並べ替え古い行は、 where not exists(~)で、インサートされない様に考えました。 しかし、下記構文では、コミットされる前だからなのか、 ダブった品番の行もインサートされようとされ、エラー となってしまいます。 どなたかご親切な方、ご教授下さいます様、 宜しくお願い致します。      記 create or replace procedure dbInsSyouhinmaster ( out_val out pls_integer ) as cursor c_1 is select 品番,商品分類,売上単価,単価実行日,登録日時,登録者 from tmpM商品単価 a where not exists(select * from M商品単価 b where trim(a.品番) = trim(b.品番)) order by 単価実行日 DESC; begin out_val:=0; for r_emp in c_1 loop if c_1%FOUND then INSERT INTO M商品単価 (品番,商品分類,売上単価,単価実行日,登録日時,登録者) VALUES(r_emp.品番,r_emp.商品分類,r_emp.売上単価,r_emp.単価実行日, r_emp.登録日時,r_emp.登録者) ; end if; out_val := out_val + 1; end loop; end;

  • PLSQlでのロールバック

    以下の様な処理をしたいのですがうまくいきません。 ・カーソルc_infoで取得した人数分、処理を行いたい。 ・ある1人が異常終了した場合は、その人の処理を全てロールバック  した後、次の人に進む。 begin for r_info in c_info loop begin 処理A  処理B  処理C exception  rollback; end; end loop exception end; こういう風に組んだのですが、 ある一人が処理Cで異常終了した時、その人の処理A,処理B がコミットされてしまっています。 どのようにすればよいでしょうか? ご教授ください。

  • カーソルについて

    カーソルってオープン時に該当データの全レコードセットを取得するんでしょうか?。 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するカーソルを使用するほうが 作法的によいのでしょうか?

  • プロシージャの記述の仕方

    テーブルAとテーブルBがあります。 テーブルAとテーブルBのレイアウト(列名・サイズetc) は、まったく同じです。唯一、違う点は、テーブルAは フラグをもっている点です。 ここで、考えていただきたいのですが テーブルAのフラグが1のレコードは、テーブルBに フラグ以外のレイアウトをINSERTし、フラグが2のレコードは、一意のコードをキーにしてDELETEを行う処理を 行いたいのですが、下記のような感じでよいのでしょうか? CREATE OR REPLACE PROCEDURE A AS CURSOR B IS SELECT * FROM A; BIGIN FOR D IN B LOOP IF D.フラグ=1 THEN INSERT INTO B VALUES(…省略 ELSIF D.フラグ=2 THEN DELETE FROM B WHERE …省略 END IF; COMMIT; END LOOP; END; / こんな感じでよいのでしょうか? よろしくお願いします。

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

  • PLSQLで

    PLSQL(Oracle9.i)で以下のことをしようとしています。 しかし、コンパイルは通るがステップ実行すると固まります。 -- 宣言部 TYPE REC_A IS RECORD( a NUMBER, b NUMBER, c NUMBER, d NUMBER, e NUMBER, f NUMBER, g NUMBER, ); TYPE B_TBL IS TABLE OF REC_A INDEX BY BINARY_INTEGER; TYPE C_TBL IS TABLE OF B_TBL INDEX BY BINARY_INTEGER; D_TBL C_TBL; -- 関数部 FOR i IN 1..3 LOOP  FOR J IN 1..3 LOOP   D_TBL(I)(J).a := 1;   D_TBL(I)(J).b := 2;   D_TBL(I)(J).c := 3;   D_TBL(I)(J).d := 4;   D_TBL(I)(J).e := 5;   D_TBL(I)(J).f := 6;   D_TBL(I)(J).g := 7;  END LOOP; END LOOP; なにぶんまだPLSQLの勉強始めて1ヶ月満たないもので、分からないことをどう伝えればいいのかも分からない状況です。 処理的には、D_TBL(I)(J)に値をいろいろセットし集計をとりCSVにはきだす処理です。 これだけでは分からないかもしれませんが、よろしくお願いします。

  • LOOP処理について

    条件に当てはまる値を10件SELECTし、 INSERTしたいのですが試せる環境がなく確認できない状態です。 もしテーブルを全件みて該当データがない場合も処理終了と したいのですが下記のような書き方でよいのでしょうか? どなたかご助言いただけないでしょうか?お願いします。 BEGIN WHILE (10=i) LOOP SELECT A INTO AA FROM TBL_A WHERE A = "xxx" INSERT INTO TBL_B (A_ID)VALUES(AA) EXIT WHEN (10=i) ; END LOOP; DBMS_OUTPUT.PUT_LINE('呼び出されます'); END;

  • 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; なにがなんだか、さっぱりわからないので、どうか、ご教授ください。

  • PLSQLで条件によりSQLを動的に変えたい

    例えば、あらかじめテーブルなどを読み、その内容により、 SQLの文そのものを非常に変えたいとします。 SQLその1 select * from TABLEA where A = 1 SQLその2 select * from TABLEA where A = 1 and B = 2 and C = 3 and D = 4 上記は例ですが、内容などにより複雑な条件式を追加したい。 ベースのSQLは非常に長い為、 例えば 完全に切り分けるのでは無く、共通の部分は共通ソースとしたい。 また、プリプロセッサみたいに、条件式が追加された場合 あたかも、初めからそのSQLのみがあり、他の制御文などをSQL文自身には追加したくない。 動的SQLでは無い方法でそのような事が可能でしょうか? ----- イメージ ----- select * from TABLEA where A = 1 IF (条件がある時のみ) B = 2 and C = 3 and D = 4 END IF; ------------------- 実際には、SQL文の中にPLSQLの制御文をうまく追加できない。

  • カーソルで取得した項目のサイズについて質問です。。

    カーソルで取得した項目のサイズについて質問です。。 SELECTした項目のサイズが下記の場合、 レコード格納変数.Cの最大サイズは(14)で、それ以上のバイト数値を代入すると エラーになると思ったのですが、エラーになりませんでした。(最大28バイトになった) レコード格納変数の取得した項目サイズは何で決まってくるのでしょうか? この項目を別テーブルのVARCHAR(20)の項目へ設定しようと思っているのですが、 理由がわからないので、このままでいいのか、サイズを考慮した設計にするべきか困っています。 <oracle 9i> TABLE1{A VARCHAR2(4), B VARCHAR2(10)} DECLARE  CURSOR カーソル変数 IS SELECT A||B AS C FROM TABLE1;  レコード格納変数 カーソル変数%ROWTYPE; BEGIN  OPEN カーソル変数  LOOP   FETCH カーソル変数 INTO レコード格納変数;   EXIT WHEN カーソル変数%NOTFOUND;    :    レコード格納変数.C := VARCAHR2(15) --代入可能?    :    INSERT 項目1 VARCHAR(20) TABLE2 レコード格納変数.C;    :  END LOOP  CLOSE カーソル変数 END;