2015-11-02 118 views
2

我已經寫了一個返回觸發器的PL/PGSQL函數,所以我可以在每行插入之前調用它。我現在意識到我也希望該函數返回新插入行的ID。我不太確定如何繼續,因爲我的函數必須返回一個觸發器。下面是一些代碼:PLPGSQL函數返回觸發器AND值

CREATE OR REPLACE FUNCTION f_insert_album() RETURNS TRIGGER AS $$ 
DECLARE 
    subj_album_id INTEGER; 
BEGIN 
    -- ... some parts where left out 
    INSERT INTO t_albums_subjective (user_id, album_id, format_id, location_id, rating) 
    VALUES (NEW.user_id, obj_album_id, NEW.format_id, NEW.location_id, NEW.rating) 
    RETURNING id INTO subj_album_id; 
RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

-- Bind insert function to trigger 
DROP TRIGGER IF EXISTS tr_v_albums_insert ON v_albums; 
CREATE TRIGGER tr_v_albums_insert INSTEAD OF INSERT ON v_albums 
    FOR EACH ROW EXECUTE PROCEDURE f_insert_album(); 

我必須保持我的函數的返回類型f_insert_album()TRIGGER,但我真的想在subj_album_id也返回值,對應於新插入行的id

有沒有辦法做到這一點?它甚至有可能嗎?顯然改變返回類型不適用於Postgres。你能否建議一種替代方法?

+1

你得所產生的標識符存儲到觸發觸發器,如果​​有合適的領域的元組,並使用'INSERT ...返回......也是頂級查詢。或者通過'LISTEN'和'NOTIFY'使用通知負載。 –

+0

感謝克雷格,雖然我不太確定我的理解非常好!你能否詳細說明你的第一個想法? –

回答

1

關鍵問題:其中要返回ID嗎?

假設您想直接從INSERT聲明中返回它,那麼您幾乎就在那裏。你已經將新生成的ID分配給一個函數參數:

相反,它分配給該行發射扳機的一列。該special variable NEW保持在觸發功能該行:

... 
RETURNING id INTO NEW.album_id; -- use actual column name in view 

然後使用RETURNING子句INSERT聲明:

INSERT INTO v_albums (user_id, format_id, location_id, rating) 
VALUES (...) 
RETURNING album_id; 

顯然,這是唯一可能的,如果有可見列在視圖中。不過,它不必在INSERT命令中進行分配。 NEW行變量的類型由視圖的定義來定義,而不是由手頭的INSERT來定義。

密切相關的問題:


對於你似乎是做(以表格的某些行授予獲得了一定的作用)的新行在即將到來的Pos​​tgres 9.5中的高級安全(RLS)可能是更方便的選擇。

+0

謝謝!這工作,和密切相關的問題幫助了很多。 –