为了举例,请考虑一个表
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()
。对于奖励积分,如果将is_active
从true
更改为fals
e,将dt_active设置为null,那将会很好,但我可以不用它。
我真的想将这个内务处理推送到数据库中,它会使客户端代码更加清晰(因为许多表(甚至表中的列元组)都可以从这种技术中受益)。
我很难过如何在触发器中拉出数据库中的当前记录(我正在使用plpgsql),以便将“then”和“now”进行比较。代码示例或代码片段的指针非常受欢迎。
答案 0 :(得分:4)
在plpgsql触发器过程中,您可以访问为您创建的名为NEW
和OLD
的特殊记录类型变量。
在UPDATE
或INSERT
触发器中,NEW
将代表新数据库行的记录。
在UPDATE
或DELETE
触发器中,OLD
将代表原始数据库行的值。
在其他语句环境中,这些记录变量将为NULL
。
因此,您似乎需要创建INSERT OR UPDATE
触发器,以查看OLD.is_active
和NEW.is_active
的值。
以下是文档页面 - http://www.postgresql.org/docs/8.1/interactive/plpgsql-trigger.html此页面包含使用NEW
和OLD
答案 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
,否则它会非常相似。