2016-07-22 26 views
1

Postgres的觸發沒有更新指定列

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.我的語法有問題嗎?我幾乎使用了文檔中指定的相同語法。

回答

1

您應該使用BEFORE而不是您的案例中的AFTER更新,並且您的代碼將完美工作。

http://sqlfiddle.com/#!15/ef408/1

你可以閱讀一些關於觸發器here

有趣樣品:

典型地,行級BEFORE觸發器用於檢查或 修改將被插入或更新的數據。例如,可以使用BEFORE觸發器將當前時間插入到 時間戳列中,或者檢查該行的兩個元素是否爲 一致。行級AFTER觸發器最明智地用於 將更新傳播到其他表,或對其他表進行一致性檢查 。這種分工的原因在於,AFTER觸發器可以確定它正在看到該行的最終值,即 而BEFORE觸發器不能;之後可能會有其他BEFORE觸發器 開火。如果您沒有特定的原因在觸發 BEFORE或AFTER之前,BEFORE情況下效率更高,因爲有關該操作的信息不必保存至 聲明結束。

+0

謝謝你的回答..我想到了BEFORE和AFTER的全新含義。生病嘗試這一點..也,你有什麼機會能夠澄清什麼確切$水平$語法意味着什麼時候創建函數?這是我無法弄清楚,但在文檔中指定的東西 – Kannaj

+1

請參閱https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING 。 –