2016-04-27 53 views
1

我對Postgres非常陌生,現在我的任務是創建一個插入後觸發的觸發器。基本上,我會讓一個腳本做一個插入,觸發這個觸發器,它將根據插入語句中的參數從另一個表中獲取一個字段,然後使用另一個表中的值更新新插入的記錄。Postgres從當前插入創建觸發器參數

  1. INSERT記錄到表1
INSERT INTO "TableA" VALUES ('ABC-101', 'John Doe', '') 

PersonID | Name | Address 
------------------------------ 
ABC-101 John Doe 
  • 該插入後,我會再火會從在表B字段搶值的觸發。
  • CREATE OR REPLACE FUNCTION fn_getaddress() 
        RETURNS trigger AS 
    $BODY$ 
    DECLARE 
        PersonID  TEXT; 
    BEGIN 
        PersonID := TG_ARGV[0]; 
    
        UPDATE "TableA" 
         SET "Address" = (SELECT "Address" 
              FROM "TableB" 
              WHERE "PersonID" = PersonID); 
        RETURN null; 
    END; 
    $BODY$ 
        LANGUAGE plpgsql VOLATILE 
        COST 100; 
    

    這裏是我的觸發器:

    CREATE TRIGGER tr_getaddress 
    AFTER INSERT 
    ON TableA 
    FOR EACH ROW 
    EXECUTE PROCEDURE fn_getaddress(personid); 
    

    所以基本上,我有TableB中(說地址),我需要爲了完成紀錄表A搶到場。我使用一個ID來引用從TableB獲取的地址。

    回答

    3

    您不需要將值傳遞給觸發器。觸發器可以從插入的行到隱含記錄new完全訪問所有列。您也不需要UPDATE語句來更改插入的行。你剛纔賦值的字段中new記錄:

    CREATE OR REPLACE FUNCTION fn_getaddress() 
        RETURNS trigger AS 
    $BODY$ 
    DECLARE 
        l_address text; 
    BEGIN 
    
        SELECT "Address" 
        into l_address 
        FROM "TableB" 
        WHERE "PersonID" = new."PersonID" 
    
        new."Address" := l_address; 
        RETURN new; --<<< important 
    END; 
    $BODY$ 
        LANGUAGE plpgsql VOLATILE 
        COST 100; 
    

    但是,您不能改變插入的行中的after觸發,你需要一個before觸發:

    CREATE TRIGGER tr_getaddress 
        BEFORE INSERT --<<< important 
        ON "TableA" 
        FOR EACH ROW 
        EXECUTE PROCEDURE fn_getaddress(); --<< no parameter necessary 
    

    但複製這樣的數據通常是一個非常糟糕的主意。如果你需要兩者的信息,你爲什麼不加入這兩張表?


    無關你的問題,但你應該真的避免那些可怕的帶引號的標識符。他們更麻煩,那麼他們是值得的