PL/SQLのCURSORでFOR UPDATEが機能しない

このQ&Aのポイント
  • カーソルの宣言で、FOR UPDATEを指定しているのに、WHERE CURRENT OFでの更新が効かない問題について質問します。
  • OracleのバージョンはOracle8i Release 8.1.6.0.0です。
  • カーソルでループを回し、各行の値を更新しようとしていますが、値が正しく書き換わりません。原因が分かる方は助言をお願いします。
回答を見る
  • ベストアンサー

【PL/SQL】CURSOR ・・・ IS SELECT・・・FOR UPDATE が機能しない

カーソルの宣言で、FOR UPDATE を指定しているのに、 WHERE CURRENT OF での更新が効きません。 エラーは発生せず、全件分ループも回っているのですが、値がまったく書き換わっていません。 Oracle Ver. = Oracle8i Release 8.1.6.0.0 CREATE OR REPLACE FUNCTION TEST_FNC RETURN BOOLEAN IS todofu_cd NUMBER(2) := 0; strSQL VARCHAR2(2000) := ''; CURSOR cur IS SELECT * FROM TEST_TBL FOR UPDATE; BEGIN For cur_rec In cur Loop DECLARE BEGIN SELECT TODOFU_CD INTO todofu_cd FROM M_POST WHERE POST_NO = cur_rec.POST_NO; EXCEPTION When NO_DATA_FOUND Then todofu_cd := 0; END; UPDATE TEST_TBL SET TODOFU_CD = todofu_cd WHERE CURRENT OF cur; COMMIT; End Loop; EXCEPTION  (省略) END; / 「CURSOR cur IS SELECT * FROM TEST_TBL FOR UPDATE;」の部分は、 「CURSOR cur IS SELECT POST_NO, TODOFU_CD FROM TEST_TBL FOR UPDATE OF TODOFU_CD; 」と記述しても結果は同じでした。 上書きしようとしている値である「todofu_cd」にきちんと望む値が格納されていること、ループが正常に回り、各行にアクセスしていることは、確認済です。 原因が分かる方がいらっしゃいましたらご教授下さい。 また、質問の内容に不備があるようでしたら、ご指摘下さい。 以上、どうかよろしくお願い致します。

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

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

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

明らかにダメなところとしては・・ コミットが書いてあることですかね。 update TEST_TBL x set TODOFU_CD=(select y.TODOFU_CD from M_POST y where y.POST_NO=x.POST_NO); update TEST_TBL set TODOFU_CD=0 where TODOFU_CD is null; の2文で書いてはダメなんでしょうかね? (件数が多すぎる?)

guest98
質問者

お礼

korochanさん、回答ありがとうございました。 原因は別にありましたが、例に挙げて頂いたSQLは、 考え付かなかったものですので、とても勉強になりました。 今後もよろしくお願いします。

guest98
質問者

補足

原因が分かりました。 変数todofu_cdと、テーブルの列名TODOFU_CDが同じであったことです。 これを訂正したら、正常に更新されました。 投稿してすぐに気づいたのですが、1件も回答のない状態での、質問者からの追記方法が分からず、そのままになってしまいました。すいませんでしたm(_ _)m あと、korochanさんのご指摘に関してですが、 このPGMで扱うテーブルは、かなり大量のデータを保持します。 その為、速度性とキャッシュ領域不足エラー解消を求めて、このような形で組んでみました。

関連するQ&A

  • PL/SQL での[CURSOR]の記述について

    CURSORを使用する際に、以下のようなことが実現できるものか分からないもので、 ご質問させていただきました。 以下のような記述で、where条件を別の変数(wk_where)に格納しておいて、 それを連結させることが可能なのかお教えいただきたいです。 もしも可能であればどのように連結させるのでしょうか? CURSOR cur出力データ IS SELECT AAA, BBB FROM AAAテーブル ; イメージとしては以下のように考えていました。 CURSOR cur出力データ IS SELECT AAA, BBB FROM AAAテーブル & wk_where ; 以上ですが、宜しくおねがいいたします。

  • 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で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にて以下のようなカーソルがあるのですが、 引数のpJYOKENをWHERE条件に追加することはできないでしょうか。 pJYOKENには(属性 = 0)のような条件が入っています。 条件はその都度違ったものが入ってくるイメージです。 cursor CURテスト (pJYOKEN IN VARCHAR2) IS SELECT 社員コード FROM テストマスタ WHERE 会社ID = '001' AND 区分 = 1; rcテスト CURテスト%rowtype; よろしくお願い致します。

  • [PL/SQL]REFCURSORが戻り値のプロシージャについて

    [PL/SQL]REFCURSORが戻り値のプロシージャについて お世話になってます タイトルの内容について、親プロシージャより引数を受け取り 子プロシージャでカーソルをオープンして、そのカーソルを親に戻す。 というプロシージャなのですが、親から実行した場合には問題ないのですが 子をSI ObjectBrowserから実行すると[実行][デバッグ]共に 押した瞬間に止まってしまいます。 下記にソースを記述します --カーソル変数の定義 CREATE OR REPLACE PACKAGE LC7BDEV.PKG_TEST_CURSOR IS  TYPE TEST_TYPE IS RECORD  (COL1 TABLE1.COL1%TYPE ,   COL2 TABLE1.COL2%TYPE ); TYPE CUR_TEST IS REF CURSOR RETURN TEST_TYPE; END; --親プロシージャ CREATE OR REPLACE PROCEDURE PD_TEST  (   in_COL_KEY IN TABLE1.COL_KEY%TYPE  ) IS  TEST_REC  PKG_TEST_CURSOR.CUR_TEST;  TEMP_COL1 TABLE1.COL1%TYPE;  TEMP_COL2  TABLE1.COL1%TYPE; BEGIN  PD_TEST_KO(in_COL_KEY,TEST_REC);  loop   fetch TEST_REC into TEMP_COL1,TEMP_COL2;   exit when TEST_REC%notfound;   dbms_output.put_line(TEMP_COL1 || ',' || TEMP_COL2);  end loop;    close TEST_REC; END; --子プロシージャ CREATE OR REPLACE PROCEDURE PD_TEST_KO  (   in_COL_KEY  IN  TABLE1.COL_KEY%TYPE ,   in_TEST_REC OUT PKG_TEST_CURSOR.CUR_TEST ,  ) IS BEGIN  OPEN in_TEST_REC FOR   SELECT COL1,COL2   FROM TABLE1   WHERE COL_KEY = in_COL_KEY END;

  • 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でカーソルを指定する方法

    以下のSQL文で、 あるストアドプロシージャを作成し、その引数の値を WHERE句の検索条件に取ってカーソルを宣言したいので すが、どうやってもエラーが出ます。結果として カーソルで格納したデータを呼び出し元に返したいの ですが…。下記の文は間違ってますか? CREATE OR REPLACE PROCEDURE ss( quote IN NUMBER result OUT CHAR ) IS CURSOR cur IS SELECT empname FROM emp WHERE empno = quote; result cur%rowtype; BEGIN OPEN cur; LOOP FETCH cur INTO result; ~ END; どうかよろしくお願いします。

  • PL/SQLの動的SQLで複数の項目を取得する方法教えて下さい。

    動的SQLで複数の項目を取得する方法で 悩んでいます。 下記の例だと、1項目しか取れません。 何か他のやり方でもいいので、複数の項目を 取得する方法を教えていただきたいです。 ********************************************* declare sql_stmt varchar2(200); wk_grp varchar2(5); wk_name varchar2(30); type cursor_type is ref cursor; cur_name cursor_type; begin wk_grp := '1u'; open cur_name for 'select 名前 from 社員表 where 所属グループ = :v1' using wk_grp; loop fetch cur_name into wk_name; exit when cur_name%notfound; dbms_output.put_line(wk_name); end loop; close cur_name; end; ********************************************* 下記のようなDBMS_SQLパッケージ?? を利用した方法がいいんでしょうかね。。。。 DBMS_SQL.COLUMN_VALUE(SQL,1,WK_NAME) DBMS_SQL.COLUMN_VALUE(SQL,2,WK_NO) よくわかってないので、宜しくお願いします。

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

  • PL/SQL)Functionの引数(文字列)をWHERE文に記述する方法

    PL/SQLで、Functionの中で実行するselect文のWhereに、Functionの 引数で受けとった値をセットしようとしています。 この引数が文字列(VARCHAR2型)の場合、どのようにWHEREで、記述したらよいのでしょうか? ご教授のほどをよろしくお願いします。 CREATE OR REPLACE FUNCTION Fn_TBL_AAA (psCODE IN VARCHAR2) IS CURSOR TBL_AAA_CUR IS SELECT * FROM TBL_AAA WHERE BBB = psCODE ; TBL_AAA_REC TTBL_AAA_CUR%ROWTYPE;       :       : ※上記のように記述すると、実行ではエラーが発生しないのですが、  取得したい結果が返ってきません。TABLE(TBL_AAA)のBBBは、  VARCHAR2なので、通常のSQL*PLUSのSELECT文ではBBB = psCODE  はBBB = 'psCODE'のように [']で括るのですが、PL/SQLの  FUNCTION内ではどのように記述すればよいのかが  わかりません。 以上、よろしくお願いいたします。