1

以下に示すような構造を持つテーブル参加者があります。

Pid    number        
name   varchar2(20)    
version  number

テーブルにレコードを挿入するたびにparticipants、バージョン =1が入力されます。

たとえば、pid=1 ,name='Gaurav' を挿入した場合、version =1get populated in で記録しますparticipants table

今、私issueはテーブルのupdate上にいます。participants

  1. 参加者テーブルの pid=1 の name ='Niharika' を更新し、pid=1 、name='Niharika' および version =2 の新しいレコードを同じテーブルに作成する必要があるとします。
  2. 再度、参加者テーブルの pid='1' の name='Rohan' を更新します。pid=1、name='Rohan'、および version=3 の新しいレコードを作成する必要があります。

どうすればこれを達成できますか?

ビューを使用してこれを達成し、トリガーの代わりに使用してビューに挿入できますが、私のソリューションには満足していません。

複合トリガーも作成しましたが、トリガー内でそのテーブルに挿入ステートメントを使用する必要があるため、それが機能していなくても、再帰エラーが発生します

4

2 に答える 2

2

本当に2つのテーブルが必要です。「ロギング」テーブルとして説明した構造で1つ作成します。すべてのレコードの履歴を保持します。同じであるが列がない「現在」と見なされる別のテーブルがありversionます。次に、「現在の」テーブルのレコードで挿入/更新が発生したときSELECT FOR UPDATEに、ログテーブルにmax(version)のメカニズム(トリガーなど)を設定し、追加して、ログテーブルに挿入します。このようにして、テーブルの変更エラーやそのような奇妙なことに遭遇することはありません。この方法では少しシリアル化がありますが、これはあなたがやろうとしていることに最も近いものです。

于 2012-07-18T22:51:47.563 に答える
-1

通常は推奨されませんが、他の追加のログテーブルなしでとにかくそれを行う方法は次のとおりです-

CREATE or REPLACE
TRIGGER part_upd
 AFTER UPDATE of name
 ON participants
 FOR EACH ROW
DECLARE
  retval BOOLEAN;
BEGIN

   retval := insert_row(:old.pid,:new.name);

END part_upd;

関数-

CREATE or REPLACE 
FUNCTION insert_row (pid1 number, name1 varchar2)
RETURN boolean
IS
    PRAGMA autonomous_transaction;
BEGIN
     INSERT INTO participants
     SELECT pid1, name1, max(vers)+1
       FROM participants
      WHERE pid = pid1;         

     COMMIT; 

     RETURN true;
END;

ロギングと例外処理を追加して、トリガーと関数を適切に微調整する必要があります。Autonomous_transactionの詳細を参照してください。

于 2012-07-19T02:33:47.723 に答える