2012-03-31 92 views
6

我想根據這個觸發更新表:PostgreSQL觸發和行更新

CREATE TRIGGER alert 
AFTER UPDATE ON cars 
FOR EACH ROW 
EXECUTE PROCEDURE update_cars(); 

觸發功能:

CREATE FUNCTION update_cars() 
RETURNS 'TRIGGER' 
AS $BODY$ 
BEGIN 
IF (TG_OP = 'UPDATE') THEN 
UPDATE hello_cars SET status = new.status 
WHERE OLD.ID = NEW.ID; 
END IF; 
RETURN NULL; 
END; 
$$ LANGUAGE plpgsql; 

觸發工作正常。 cars表更新後,hello_cars表會更新,但每行中的狀態列會更新幷包含相同的新狀態!它必須根據汽車ID進行更新。
我認爲我的問題是在條件:WHERE OLD.ID = NEW.ID;,但我不能說出了什麼問題。

在此先感謝。

回答

5

OLDNEW是觸發觸發器的行的別名。所以,當你執行如下語句

UPDATE cars SET status='xyz' WHERE cars.id = 42; 

則觸發功能將執行

UPDATE hello_cars SET status='xyz' WHERE 42 = 42 

的部分42=42始終是真實的。因此更新了hello_cars中的每一行。

你真的想要的東西像

[...]WHERE hello_cars.id = OLD.ID 

或短一點

[...]WHERE id = OLD.ID 

但你也需要考慮會發生什麼,如果初始更新改變cars.id。在這種情況下,OLD.ID不等於NEW.ID。在這種情況下,hello_cars表中應該發生什麼?但那是另一個問題。

+0

非常感謝你! – Noon 2012-04-01 05:49:38

+0

@Shadin:不客氣。請參閱[常見問題/如何問](http://stackoverflow.com/faq#howtoask)如何接受最有幫助的答案。 – 2012-04-01 07:18:43

6

OLD.IDNEW.ID被引用cars的更新行,因此(除非你改變cars的ID)將始終評估爲真,爲此在hello_cars所有行被更新。

我想你可能想:

UPDATE hello_cars 
    SET status = new.status 
WHERE id = new.id; 

這是假設存在這樣的carsid匹配的表hello_carsid

+0

非常感謝你!它很好用 – Noon 2012-04-01 05:49:59