0

列車の旅の詳細を取得するカーソルがあります。レコードをループすると、次の駅の ETA (到着時間) が更新されます。この値は、その駅の ETD (出発時刻) を計算するために使用されます。カーソルを開いたときに古い値ではなく、レコードがその旅行の次の駅をフェッチするときに ETA の更新された値を使用して ETD を計算したいと考えています。これは可能ですか?

CURSOR CUR_SCN IS
SELECT TRIP_ID,
TRAIN_ID,
STATION_ID,
ETA
FROM TRIP_DTL
WHERE ....;

FOR rec IN CUR_SCN
   calculate and update ETD for current rec.STATION_ID

   ld_eta := Business logic goes here for calculating next station ETA for the TRIP

   UPDATE TRIP_DTL
   SET ETA = ld_eta
   WHERE STATION_ID = next station
   AND TRIP_ID = rec.TRIP_ID;
END LOOP;
4

2 に答える 2

1

カーソルを開くと、データの固定ビューが表示されます。「新しい」値を取得する唯一の方法は、再クエリすることです。

于 2012-04-23T13:59:07.480 に答える
1

Adam Hawkes が言うように、カーソル for ループで新しい値を「取得」する方法はありませんが、これを回避する方法はあります。

  1. グローバル一時テーブルを使用します。これを更新し、もう一度クエリを実行してから、すべてを実際のテーブルに入れます。このルートはあまり好きではありませんが、希望どおりに動作します。

  2. データをユーザー定義型に一括収集し、この値を使用して必要なものを計算します。次のようなもの。これには、テーブルで実行される DML が少なくなるという利点があり、rowid を使用して更新できるため、更新が高速になります。

    declare
    
       cursor cur_scn is
        SELECT rowid as rid, TRIP_ID, TRAIN_ID, STATION_ID, ETA
          FROM TRIP_DTL
         WHERE ....
         ORDER BY SOMETHING;
    
        type t__scn is table of cur_scn%rowtype index by binary_integer;
        t_scn t__scn;
    
    begin
    
       open cur_scn;
       fetch cur_scn bulk collect into t_scn;
    
       for i in t_scn.first + 1.. t_scn.last loop
          t_scn(i).eta := t_scn(i - 1).eta + business_logic;
       end loop;
    
       forall i in t_scn.first .. t_scn.last
          update trip_dtl
             set eta = t_scn(i).eta
           where rowid = t_scn(i).rid;
    
       close cur_scn;
    
    end;
    
  3. 常にすべてを更新しなければならない方法はあまり好きではありませんが、頭のてっぺんからデータを保存するより良い方法を思いつくことはできませんが、調査する必要があります。

于 2012-04-23T19:48:26.593 に答える