sql >> データベース >  >> RDS >> PostgreSQL

トリガー関数内で、更新されているフィールドを取得する方法

    「ソース」が「識別子を送信」し​​ない場合、列は変更されません。次に、現在のUPDATEかどうかを検出できません 最後のソースと同じソース、または列をまったく変更しなかったソースによって実行されました。つまり、これは正しく機能しません。

    「ソース」がセッション情報機能によって識別できる場合は、それを使用できます。いいね:

    NEW.column = session_user;
    

    更新ごとに無条件に。

    一般的な解決策

    元の問題を解決する方法を見つけました。列は任意のデフォルト値に設定されます 列が更新されていない場所を更新します (SETにはありません UPDATEのリスト 。

    重要な要素は列ごとのトリガーです PostgreSQL9.0で導入-UPDATE OFを使用した列固有のトリガー column_name 条項。

    リストされた列の少なくとも1つがUPDATEのターゲットとして言及されている場合にのみ、トリガーが起動します。 コマンド。

    これが、列が古い値と同じ新しい値で更新されたか、まったく更新されなかったかを区別するために私が見つけた唯一の簡単な方法です。

    1つできた current_query()によって返されたテキストも解析します 。しかし、それはトリッキーで信頼できないようです。

    トリガー関数

    col列を想定しています 定義されたNOT NULL

    ステップ1: colを設定します NULLへ 変更されていない場合:

    CREATE OR REPLACE FUNCTION trg_tbl_upbef_step1()
      RETURNS trigger AS
    $func$
    BEGIN
       IF OLD.col = NEW.col THEN
          NEW.col := NULL;      -- "impossible" value
       END IF;
    
       RETURN NEW;
    END
    $func$  LANGUAGE plpgsql;
    

    ステップ2: 古い値に戻します。トリガーは、値が実際に更新された場合にのみ発生します (以下を参照):

    CREATE OR REPLACE FUNCTION trg_tbl_upbef_step2()
      RETURNS trigger AS
    $func$
    BEGIN
       IF NEW.col IS NULL THEN
          NEW.col := OLD.col;
       END IF;
    
       RETURN NEW;
    END
    $func$  LANGUAGE plpgsql;
    

    ステップ3: これで、不足している更新を識別し、代わりにデフォルト値を設定できます:

    CREATE OR REPLACE FUNCTION trg_tbl_upbef_step3()
      RETURNS trigger AS
    $func$
    BEGIN
       IF NEW.col IS NULL THEN
          NEW.col := 'default value';
       END IF;
    
       RETURN NEW;
    END
    $func$  LANGUAGE plpgsql;
    

    トリガー

    ステップ2のトリガー 列ごとに発射されます!

    CREATE TRIGGER upbef_step1
      BEFORE UPDATE ON tbl
      FOR EACH ROW
      EXECUTE PROCEDURE trg_tbl_upbef_step1();
    
    CREATE TRIGGER upbef_step2
      BEFORE UPDATE OF col ON tbl                -- key element!
      FOR EACH ROW
      EXECUTE PROCEDURE trg_tbl_upbef_step2();
    
    CREATE TRIGGER upbef_step3
      BEFORE UPDATE ON tbl
      FOR EACH ROW
      EXECUTE PROCEDURE trg_tbl_upbef_step3();

    トリガー名 アルファベット順に起動されるため、関連性があります(すべてBEFORE UPDATE )!

    この手順は、「列ごとではないトリガー」など、UPDATEのターゲットリストをチェックする他の方法で簡略化できます。 トリガーで。しかし、私にはこれに対するハンドルがありません。

    colの場合 NULLにすることができます 、他の「不可能な」中間値を使用して、NULLを確認します さらにトリガー機能1:

    IF OLD.col IS NOT DISTINCT FROM NEW.col THEN
        NEW.col := '#impossible_value#';
    END IF;
    

    それに応じて残りを適応させます。



    1. SQL Server(T-SQL)でAM/PMを時間値に追加する方法

    2. KNIME

    3. Oracleのデータベーススキーマをダンプファイルにエクスポートする方法

    4. データベース全体で空の文字列('')をNULLに設定します