2016-05-09 19 views
2

現在、OracleからPostgresに移行中です。オラクルでは、このような文作成のトリガーがあります。必要な場合は、Oracleにリモート例外処理の詳細を読むことができPostgresトリガのリモート例外処理?

create or replace TRIGGER action2md           
    AFTER INSERT OR UPDATE OR DELETE 
    ON action                
    DECLARE 
    Mutating_table EXCEPTION; 
    PRAGMA EXCEPTION_INIT (Mutating_table, -4091); 
BEGIN 
    UPDATE global_tables_md             
    SET moddate = SYSTIMESTAMP 
    WHERE table_name='action';            
EXCEPTION 
    WHEN Mutating_table THEN 
     NULL; 
END; 

hereをトリガします。

私たちは、データベースの移行を支援するためにora2pg使用していて、それは次のようにトリガー作成文を変更:

DROP TRIGGER IF EXISTS action2md ON action CASCADE; 
CREATE OR REPLACE FUNCTION trigger_fct_action2md() RETURNS trigger AS $BODY$ 
DECLARE 
    Mutating_table EXCEPTION; 
    PRAGMA EXCEPTION_INIT (Mutating_table, -4091); 
BEGIN 
    UPDATE global_tables_md 
    SET moddate = CURRENT_TIMESTAMP 
    WHERE table_name='action';            
IF TG_OP = 'DELETE' THEN 
    RETURN OLD; 
ELSE 
    RETURN NEW; 
END IF; 

EXCEPTION 
    WHEN Mutating_table THEN 
     NULL; 
END 
$BODY$ 
LANGUAGE 'plpgsql'; 

CREATE TRIGGER action2md 
    AFTER INSERT OR UPDATE OR DELETE ON action FOR EACH STATEMENT 
    EXECUTE PROCEDURE trigger_fct_action2md(); 

これはエラーになり[42704]はERROR:タイプ「例外」が存在しません。

問題はDECLAREブロックと関係があります。 Postgresで同等のトリガーをどのように作成できるかについての洞察はありますか?

答えて

2

ora2pgはOracleのトリガープラグマと例外を処理できないようです。そのため、PostgreSQLでは意味を持たないPGスクリプトに同じコードが追加されています。

変異表は、トリガーによって自身が更新され、新しいトリガー(またはそのようなもの)が発生すると、Oracleによってトリガーされる例外です。このトリガはそのような状況に対応しており、例外をキャッチして何もしていないようです。意味がないので、PostgreSQL関数のDECLAREセクションとEXCEPTIONセクションをすべて削除する必要があります。

PostgreSQLでは、トリガは後続の(ネストされた)トリガを引き起こす可能性があり、対処するのは開発者の責任です。この回答は、PostgreSQLのネストされたトリガーを扱う方法の例を示しています:https://stackoverflow.com/a/14262289/3886053

+0

ブロックTG_OP = 'DELETE' THEN RETURN OLD; ELSE NEW; END IF; ora2pgトリガ機能を示しますか? – irrational

+0

@irrational OLDおよびNEWレコードは、DELETE、UPDATEおよびINSERTトリガーで必要に応じて定義されます。 DELETEトリガーにはNEWレコードが定義されていないため、関数はOLDを返さなければなりません。 BEFOREトリガーでは、OLDがNULLでない場合はDELETEが行を削除します。そうでない場合は、NEWの値を持つ行を更新または挿入します(これはトリガー内で変更できます)。 –