- ベストアンサー
カーソルループ内部でログを出力
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が出力されると考えたのですが、 どちらも更新後の値が出力されるのは何故でしょうか? お手数をお掛け致しますが、よろしくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>処理の前後でSELECTする事は可能であると思いますが、 >カーソル内でまとめて行いたいです。 >カーソル内でIF文の前後の値を出力する事は可能でしょうか? カーソルでselectした結果に対しUpdate~where current of カーソル; を実行しても、既にフェッチ済みの内容が変わることは無いので、 再度selectしない事には変更後の内容は抽出できません。 二度読みが嫌であるならカーソルで取得したものを変数に入れて変数で操作したほうがいいのかもしれません。 >どちらも更新後の値が出力されるのは何故でしょうか? 私の環境で確認してみましたが、両方とも古い値でしたよ? 2回実行してませんか?
その他の回答 (1)
- MZ-80B
- ベストアンサー率56% (46/81)
常に使える句ではないですが UPDATE にRETURNING句を使用してみては?
お礼
お返事が遅れまして申し訳ありません。 RETURNING句というものがあったのですね。 初めて知りました。 そちらを利用したところ、 思ったとおりの結果が得られました。 ご回答ありがとうございました。
お礼
お返事が遅れまして申し訳ありません。 やはり無理なのですね。 実行結果については、見間違いなのか、 勘違いなのか・・・原因はハッキリしませんが、 フェッチ済の~というお話を元に考えると、 なんらかの勘違いをしていたものと思われます。 お騒がせして申し訳ありません。 ご回答ありがとうございました。