当布尔字段设置为true时,postgres更新日期字段

时间:2009-09-11 10:43:08

标签: postgresql date triggers plpgsql

为了举例,请考虑一个表

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_activefalse更改为true时,我想要做的是,dt_active设置为now()。对于奖励积分,如果将​​is_activetrue更改为fals e,将dt_active设置为null,那将会很好,但我可以不用它。

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

我很难过如何在触发器中拉出数据库中的当前记录(我正在使用plpgsql),以便将“then”和“now”进行比较。代码示例或代码片段的指针非常受欢迎。

4 个答案:

答案 0 :(得分:4)

在plpgsql触发器过程中,您可以访问为您创建的名为NEWOLD的特殊记录类型变量。

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

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

在其他语句环境中,这些记录变量将为NULL

因此,您似乎需要创建INSERT OR UPDATE触发器,以查看OLD.is_activeNEW.is_active的值。

以下是文档页面 - http://www.postgresql.org/docs/8.1/interactive/plpgsql-trigger.html此页面包含使用NEWOLD

的plpgsql的示例代码

答案 1 :(得分:4)

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 Triggers manual,以及额外的点 - 整个plPgSQL文档。

答案 2 :(得分:2)

您是否尝试过manual

每个触发器功能都有一些自动变量。如果是更新触发器,则可以通过OLD访问旧行值,并通过NEW

访问更改后的值

您只需按OLD.is_active检查OLD的列值即可。您可以像更改NEW.dt_active := now();

一样更改要放入数据库的值

希望这一切。

答案 3 :(得分: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,否则它会非常相似。