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当从falseto更改为时,我想做的true是 fordt_active设置为now()is_active对于奖励积分,如果从更改true为e会很好fals,dt_active 设置为 null,但我可以没有它。

我真的很想将这种内务处理推送到数据库中,它会使客户端代码更加简洁(因为许多表(甚至表中的列元组)都可以从这种技术中受益)。

我很困惑如何在触发器中提取数据库中的当前记录(我正在使用 plpgsql),以便将“then”与“now”进行比较。非常感谢指向代码示例或片段的指针。

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 触发器过程中,您可以访问一些特殊的记录类型变量,这些变量称为NEWOLD为您创建。

UPDATEorINSERT触发器中,NEW将表示新数据库行的记录。

UPDATEorDELETE触发器中,OLD将表示原始数据库行的值。

在其他语句上下文中,这些记录变量将是NULL.

因此,您似乎需要创建一个INSERT OR UPDATE查看 和 值的OLD.is_active触发器NEW.is_active

这是文档页面 - http://www.postgresql.org/docs/8.1/interactive/plpgsql-trigger.html此页面包含 plpgsql 的示例代码,它使用NEWOLD

于 2009-09-11T10:57:56.253 回答
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 回答
2

你试过手册吗?

每个触发函数都有一些自动变量。在更新触发器的情况下,旧行值可以通过访问OLD,更改的值可以通过NEW

您可以简单地检查 OLD 的列值OLD.is_active。同样的方式,您可以更改要放入数据库中的值,例如NEW.dt_active := now();

希望这有帮助。

于 2009-09-11T10:54:59.130 回答