2012-03-31 67 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