4

例のために、テーブルを考えてみましょう

create table foo (
  contents text NOT NULL,
  is_active boolean NOT NULL DEFAULT false,
  dt_active date
)

レコードを挿入します:

insert into foo (contents) values ('bar')

ここまでは順調ですね。後で、レコードを「アクティブ化」したいと思います。

update foo set is_active = true

is_activeに変更されfalseたときにやりたいことtrueは、dt_activeに設定されていnow()ます。ボーナスポイントについては、をeにis_active変更し、dt_activeをnullに設定すると便利ですが、それがなくても生活できます。truefals

このハウスキーピングをデータベースにプッシュしたいのですが、クライアントコードがはるかにクリーンになります(多くのテーブル(およびテーブル内の列タプルでさえ)がこの手法の恩恵を受ける可能性があるため)。

「then」と「now」を比較するために、トリガーでデータベース内の現在のレコードを引き出す方法(私はplpgsqlを使用しています)に困惑しています。コード例またはスニペットへのポインタは大歓迎です。

4

4 に答える 4

5
CREATE OR REPLACE FUNCTION trg_update_foo() RETURNS TRIGGER AS
$BODY$
BEGIN
    IF OLD.is_active = false AND NEW.is_active = true THEN
        NEW.dt_active := now();
    ELSIF OLD.is_active = true AND NEW.is_active = false THEN
        NEW.dt_active := NULL;
    END IF;
    RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql';
CREATE TRIGGER trg_update_foo BEFORE UPDATE ON foo FOR EACH ROW EXECUTE PROCEDURE trg_update_foo();

動作するはずです。詳細については、pl / PgSQLトリガーのマニュアルを確認し、追加のポイントについては、plPgSQLドキュメント全体を確認してください。

于 2009-09-11T11:20:04.450 に答える
4

plpgsqlトリガープロシージャ内で、呼び出されて作成されたいくつかの特別なレコード型変数にアクセスできNEWますOLD

UPDATEまたはINSERTトリガーで、はNEW新しいデータベース行のレコードを表します。

UPDATEまたはDELETEトリガーで、はOLD元のデータベース行の値を表します。

他のステートメントコンテキストでは、これらのレコード変数はになりますNULL

したがって、とINSERT OR UPDATEの値を調べるトリガーを作成する必要があるようです。OLD.is_activeNEW.is_active

ドキュメントページは次のとおりです-http: //www.postgresql.org/docs/8.1/interactive/plpgsql-trigger.htmlNEWこのページには、およびを使用するplpgsqlのサンプルコードが含まれています。OLD

于 2009-09-11T10:57:56.253 に答える
2

マニュアルを試しましたか?

すべてのトリガー関数にはいくつかの自動変数があります。更新トリガーの場合、古い行の値にはを介してアクセスできOLD、変更された値はを介してアクセスできますNEW

OLDの列の値は。で簡単に確認できますOLD.is_active。データベースに配置する値を次のように変更できるのと同じ方法です。NEW.dt_active := now();

これがうまくいくことを願っています。

于 2009-09-11T10:54:59.130 に答える
2
CREATE FUNCTION actrigger() RETURNS TRIGGER AS $$ BEGIN
    IF TG_OP='UPDATE' THEN
        IF NEW.is_active THEN
            IF NOT OLD.is_active THEN
                NEW.dt_active := current_date;
            END IF;
        ELSIF NEW.dt_active IS NOT NULL
            NEW.dt_active := NULL;
        END IF;
    END IF;
    RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER foobefore BEFORE UPDATE ON foo FORR EACH ROW
    EXECUTE PROCEDURE actrigger();

INSERTそして、あなたはそれが参照するべきではないことを除いてかなり似ているであろうことも世話をすることができますOLD

于 2009-09-11T11:17:45.847 に答える