我有以下用户表
Column | Type | Modifiers
-----------+--------------------------+-------------------------------------------------------
id | integer | not null default nextval('accounts_id_seq'::regclass)
username | character varying(40) |
email | character varying(40) |
password | character varying |
join_date | timestamp with time zone | default now()
xp | integer | default 0
level | integer | default 1
provider | character varying |
is_admin | boolean | default false
我正在尝试创建一个触发器,它会查看用户xp INTEGER并根据给定的xp更新他的级别
这是我的下面的功能和必要的触发器
CREATE OR REPLACE FUNCTION set_user_level() RETURNS TRIGGER AS $level$
BEGIN
CASE
WHEN NEW.xp BETWEEN 100 AND 200 THEN
NEW.level = 2;
WHEN NEW.xp BETWEEN 200 AND 400 THEN
NEW.level = 3;
ELSE
NEW.level = 1;
END CASE;
RETURN NEW;
END;
$level$ LANGUAGE plpgsql;
CREATE TRIGGER set_user_level AFTER UPDATE ON account FOR EACH ROW EXECUTE PROCEDURE set_user_level();
然而,每当我更新用户xp。用户级别仍然保持为1.我的语法有问题吗?我几乎使用了与文档中指定的语法相同的语法。
答案 0 :(得分:1)
在您的情况下,您应该使用BEFORE
而不是AFTER
更新,并且您的代码将完美运行。
请参阅http://sqlfiddle.com/#!15/ef408/1
您可以阅读一些关于触发器here的内容。
有趣的样本:
通常,行级BEFORE触发器用于检查或 修改将要插入或更新的数据。例如,a BEFORE触发器可用于将当前时间插入到 timestamp列,或检查行的两个元素是什么 是一致的。行级AFTER触发器最明智地用于 将更新传播到其他表,或进行一致性检查 对其他桌子。这种分工的原因是: AFTER触发器可以确定它正在查看行的最终值, 虽然BEFORE触发器不能;可能还有其他BEFORE触发器 在它之后开火。如果您没有特定的理由进行触发 之前或之后,BEFORE案例更有效率,因为 有关操作的信息不必保存到结束 言。