プロが教える店舗&オフィスのセキュリティ対策術

DECLARE
CURSOR EMP_CUR IS
SELECT SALARY FROM EMP
WHERE DEPT_NO = 10 FOR UPDATE;
BEGIN
FOR EMP_REC IN EMP_CUR LOOP
DBMS_OUTPUT.PUT_LINE( '変更前:' || EMP_REC.SALARY );
--SALARYが2500以下なら100を加える
IF EMP_REC.SALARY < 2500 THEN
UPDATE EMP SET SALARY = SALARY + 100
WHERE CURRENT OF EMP_CUR;
DBMS_OUTPUT.PUT_LINE( '処理件数:' || SQL%ROWCOUNT );
END IF;
DBMS_OUTPUT.PUT_LINE( '変更後:' || EMP_REC.SALARY );
END LOOP;
END;
/

上記のようなSQLで、
変更前のSALARYと変更後のSALARYを出力したいのですが、
変更前と変更後のEMP_REC.SALARYで、同じ値が出力されました。

処理の前後でSELECTする事は可能であると思いますが、
カーソル内でまとめて行いたいです。
カーソル内でIF文の前後の値を出力する事は可能でしょうか?

また、もう1点質問があります。
それは、SALARYの値が、どちらも更新された値が出力される事についてです。

例:DEPT_IDが10で、SALARYが1000の従業員が居た場合。
  変更前:1100
  変更後:1100

EMP_REC.SALARYの値が、DECLAREで定義されたカーソルのデータならば、
1000が出力されると考えたのですが、
どちらも更新後の値が出力されるのは何故でしょうか?

お手数をお掛け致しますが、よろしくお願い致します。

A 回答 (2件)

常に使える句ではないですが


UPDATE にRETURNING句を使用してみては?
    • good
    • 0
この回答へのお礼

お返事が遅れまして申し訳ありません。

RETURNING句というものがあったのですね。
初めて知りました。
そちらを利用したところ、
思ったとおりの結果が得られました。

ご回答ありがとうございました。

お礼日時:2007/02/03 11:21

>処理の前後でSELECTする事は可能であると思いますが、


>カーソル内でまとめて行いたいです。
>カーソル内でIF文の前後の値を出力する事は可能でしょうか?

カーソルでselectした結果に対しUpdate~where current of カーソル;
を実行しても、既にフェッチ済みの内容が変わることは無いので、
再度selectしない事には変更後の内容は抽出できません。
二度読みが嫌であるならカーソルで取得したものを変数に入れて変数で操作したほうがいいのかもしれません。

>どちらも更新後の値が出力されるのは何故でしょうか?

私の環境で確認してみましたが、両方とも古い値でしたよ?
2回実行してませんか?
    • good
    • 0
この回答へのお礼

お返事が遅れまして申し訳ありません。

やはり無理なのですね。
実行結果については、見間違いなのか、
勘違いなのか・・・原因はハッキリしませんが、
フェッチ済の~というお話を元に考えると、
なんらかの勘違いをしていたものと思われます。
お騒がせして申し訳ありません。

ご回答ありがとうございました。

お礼日時:2007/02/03 11:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す