「ソース」が「識別子を送信」しない場合、列は変更されません。次に、現在の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;
それに応じて残りを適応させます。