Postgres从当前插入创建触发器传递参数

时间:2016-04-27 20:23:37

标签: postgresql function triggers plpgsql

我对Postgres很新,现在我的任务是创建一个在插入后触发的触发器。基本上,我会让脚本执行插入操作,触发根据Insert语句中的参数从另一个表中获取字段的触发器,然后使用另一个表中的值更新新插入的记录。

  1. INSERT记录到表1。
  2. INSERT INTO "TableA" VALUES ('ABC-101', 'John Doe', '')
    
    PersonID  |  Name  |  Address
    ------------------------------
    ABC-101    John Doe 
    
    1. 在此插入之后,我将触发将从TableB中的字段中获取值的触发器。
    2. 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中有一个字段(比如说地址),我需要抓取它以完成TableA中的记录。我使用ID来引用从TableB获取的地址。

1 个答案:

答案 0 :(得分: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

但是复制这样的数据通常是一个非常糟糕的主意。如果您需要两者的信息,为什么不加入这两个表呢?

与您的问题无关,但您应该真的避免使用那些可怕的带引号的标识符。他们是值得的,他们更麻烦