对SQL函数中的“NEW”关键字感到困惑

时间:2017-02-16 17:09:48

标签: sql postgresql triggers

我对SQL / PostgreSQL比较陌生,我们刚开始使用触发器和函数/程序。

这是两个相关的表格

CREATE TABLE Planes (
    regnr TEXT PRIMARY KEY,
    capacity INT NOT NULL
);

CREATE TABLE AvailableFlights (
    date TEXT PRIMARY KEY,
    price INT NOT NULL,
    nbrOfFreeSeats INT NOT NULL,
    flight TEXT NOT NULL REFERENCES Flights(code),
    plane TEXT NOT NULL REFERENCES Planes(regnr)
);

表“航班”包含更多关于到达等的信息。无论如何,现在我有这样的功能:

CREATE OR REPLACE FUNCTION update_plane() RETURNS TRIGGER AS $$
DECLARE
    size_difference INTEGER;
BEGIN
    size_difference := (SELECT capacity FROM Planes WHERE regnr = new.plane) - (SELECT capacity FROM Planes WHERE regnr = old.plane);

    IF(NEW.numberOfFreeSeats + size_difference < 0) THEN
        RAISE EXCEPTION 'Plane too small';
    ELSE NEW.numberOfFreeSeats := NEW.numberOfFreeSeats + size_difference;
    END IF;

    RETURN NEW;
END
$$ LANGUAGE 'plpgsql';

触发器:

CREATE TRIGGER UpdatePlane BEFORE UPDATE ON AvailableFlights
FOR EACH ROW
WHEN (NEW.plane <> OLD.plane)
EXECUTE PROCEDURE update_plane();

所以我的问题是:如何在没有SELECT和FROM和WHERE条件的情况下编写NEW.nbrOfFreeSeats?它如何知道哪一行要相应改变?因为触发器只会在我写“UPDATE table SET plane ='newVal'WHERe plane ='oldVal'之类的东西时被触发,所以在我看来我永远不会说明我想改变哪些nbrSeats。或者它是暗示哪个飞机我要改变?(澄清一下:它工作正常,我只是好奇为什么)。

我希望我有任何意义,这是我在stackoverflow上的第一篇文章,所以我希望我没有发布太多错误发布此内容(欢迎提出任何反馈意见,有点匆匆发布):)提前谢谢。

1 个答案:

答案 0 :(得分:3)

作为documentation states

  

NEW

     

数据类型记录;保存新数据库行的变量   行级触发器中的INSERT / UPDATE操作。

以及

  

在[...]之前触发行级触发器返回与原始值不同的行值会改变将插入或更新的行。

示例&#34;示例39-3。 PL / pgSQL触发程序&#34;该页面也可能有所帮助。