PostgreSQL触发器和行更新

Noo*_*oon 7 postgresql triggers

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

CREATE TRIGGER alert 
AFTER UPDATE ON cars
FOR EACH ROW
EXECUTE PROCEDURE update_cars();
Run Code Online (Sandbox Code Playgroud)

触发功能:

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;
Run Code Online (Sandbox Code Playgroud)

触发器工作正常.cars更新表时,表会更新,hello_cars但每行中的状态列都会更新并包含相同的新状态!必须根据车辆ID更新.
我认为我的问题是有条件的:WHERE OLD.ID = NEW.ID;但我不知道出了什么问题.

提前致谢.

A.H*_*.H. 7

OLD并且NEW是触发触发器的行的别名.所以当你执行一个类似的语句时

UPDATE cars SET status='xyz' WHERE cars.id = 42;
Run Code Online (Sandbox Code Playgroud)

然后触发器功能将执行

UPDATE hello_cars SET status='xyz' WHERE 42 = 42
Run Code Online (Sandbox Code Playgroud)

这部分42=42总是如此.所以每一行hello_cars都会更新.

你真的想要这样的东西

 [...]WHERE hello_cars.id = OLD.ID
Run Code Online (Sandbox Code Playgroud)

或者更短一些

 [...]WHERE id = OLD.ID
Run Code Online (Sandbox Code Playgroud)

但是,如果初始更新发生变化,您还需要考虑会发生什么cars.id.在这种情况下OLD.ID是不平等的NEW.ID.hello_cars在这种情况下,表中会发生什么?但这是另一个问题.


a_h*_*ame 6

OLD.ID并且NEW.ID正在引用表的更新行中的,cars因此(除非您更改ID cars)将始终评估为true,因此更新hello_cars中的所有行.

我想你可能想要:

UPDATE hello_cars
   SET status = new.status
WHERE id = new.id;
Run Code Online (Sandbox Code Playgroud)

这假定有一个列id在表中hello_cars的相匹配idcars.