0

UPDATE my_dblist SET passive_servername = v_newpassive WHERE server = :NEW.server AND dbname = :NEW.dbname;私の問題は、更新ステートメントが発生していないように見えるという事実を除いて、以下に詳述されているトリガーが正しく実行されている ように見えることです。古いレコードは削除され、履歴に正しく挿入されますが、新しいレコードには、passive_servername の下にリストされている古いアクティブ サーバーがありません。これは、自律的であることと関係があるのではないかと感じていますか?

create or replace
TRIGGER cluster_check
AFTER INSERT ON my_dblist
FOR EACH ROW
DECLARE
pragma autonomous_transaction;
v_duplicates NUMBER;
v_newpassive varchar2(30);
BEGIN
SELECT count(*) INTO v_duplicates FROM my_dblist WHERE passive_servername         = :new.server and dbname = :new.dbname order by 1;
IF v_duplicates > 0
THEN 
SELECT server INTO v_newpassive FROM my_dblist WHERE passive_servername = :NEW.server AND dbname = :NEW.dbname ORDER BY 1;
UPDATE my_dblist
SET passive_servername = v_newpassive WHERE server = :NEW.server AND dbname = :NEW.dbname;
INSERT INTO my_dblist_history 
SELECT * FROM my_dblist WHERE passive_Servername = :NEW.server AND dbname = :NEW.dbname;
DELETE FROM my_dblist 
WHERE passive_Servername = :NEW.server AND dbname = :NEW.dbname;
END IF;
commit;
END;
4

1 に答える 1

5

トリガーは、自律型トランザクションを使用するように宣言されています。トリガーの唯一の目的が、変更が最終的に正常にコミットされたかどうかに関係なく、保持する必要があるデータの行を変更しようとする試みをログに記録することでない限り、これはほとんどの場合エラーです。この場合、それが問題の原因である可能性もあります。トリガーは自律型トランザクションであるため、トリガー文によって行われたコミットされていない変更は表示されません。UPDATEたとえば、これらの行は、定義上、別のトランザクションで実行されたコミットされていない作業であるため、トリガーが起動される原因となった行はステートメントには表示されません。

一歩下がって、解決しようとしている問題を正確に説明できますか? 自律型トランザクションを使用して、変化するテーブルの例外を回避しようとしていると仮定しています。それはほとんどの場合間違いです。変化するテーブルの例外は、ほとんどの場合、データ モデルに問題があることを示しているため、エラーを回避するよりもデータ モデルを修正する方がはるかに適切です。データ モデルを修正できない場合は、複数のトリガーを使用して変更テーブル エラーを回避する必要があります。

于 2012-06-15T16:26:40.570 に答える