2017-02-16 198 views
3

我對SQL/PostgreSQL相對比較陌生,我們剛剛開始使用觸發器和函數/過程。對SQL函數中的「NEW」關鍵字感到困惑

這是兩個相關的表

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(); 

所以我的問題是這樣的:我怎麼能簡單地寫NEW.nbrOfFreeSeats witho用FROM和WHERE條件選擇SELECT?它是如何知道哪一行相應改變的?因爲觸發器只有在我寫了「UPDATE table SET plane ='newVal'WHERE plane ='oldVal'之類的東西時纔會觸發,所以在我看來,我永遠不會說明我想改變哪個nbrSeats。飛機我改變了?(澄清:它工作正常,我只是好奇,爲什麼)。

我希望我有任何意義,這是我在stackoverflow上的第一篇文章,所以我希望我沒有做太多的錯誤張貼本(任何反饋意見會受到歡迎,雖然,有點貼這一個急速):)在此先感謝。

回答

3

由於documentation states

NEW

數據類型RECORD;在行級觸發器中保存新數據庫行的變量爲 INSERT/UPDATE操作。

並且還

行級觸發器燒製BEFORE [...]返回從NEW的原始值不同的行值改變將被插入或更新的行。

該頁面中的示例「例39-3 PL/pgSQL觸發器過程」也可能有幫助。

+0

哦,我想我明白了......但在前面的例子中,我們也做了一個函數,然後當我們想爲頂部聲明的東西賦值時,我們必須寫ticket_price:=(SELECT price。 WHERE flight = NEW.flight)。爲什麼我們不能寫ticket_price:= price? – Yuna

+1

@Yuna不確定。在這種情況下你嘗試過NEW.price嗎?也許你可以發佈一些關於這種情況的代碼或者創建一個新的問題? – nbouchet

+0

對不起,延期回覆,但我解決了,再次感謝! – Yuna