PostgreSQL 触发器和更新的行

9

我正在尝试根据此触发器更新表:

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; 但我无法确定问题所在。
提前感谢您的帮助。
2个回答

11

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 中应该怎么处理呢?但这是另一个问题。


@Shadin:不用谢。请查看FAQ/如何提问,了解如何接受帮助你最多的答案。 - A.H.

6
OLD.IDNEW.ID是引用cars表中更新行中的值,因此(除非您更改cars中的ID),它们始终会评估为真,因此所有在hello_cars中的行都将被更新。我认为你可能想要的是:
UPDATE hello_cars
   SET status = new.status
WHERE id = new.id;

这里假设在 hello_cars 表中有一列名为 id,并且它与 cars 表中的 id 匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接