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

Smi*_*ley 1 postgresql triggers function plpgsql

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

  1. INSERT 记录到表 1。
INSERT INTO "TableA" VALUES ('ABC-101', 'John Doe', '')

PersonID  |  Name  |  Address
------------------------------
ABC-101    John Doe 
Run Code Online (Sandbox Code Playgroud)
  1. 在此插入之后,我将触发触发器,该触发器将从 TableB 中的字段中获取值。
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;
Run Code Online (Sandbox Code Playgroud)

这是我的触发器:

CREATE TRIGGER tr_getaddress
AFTER INSERT
ON TableA
FOR EACH ROW
EXECUTE PROCEDURE fn_getaddress(personid);
Run Code Online (Sandbox Code Playgroud)

所以基本上,我在 TableB 中有一个字段(比如地址),我需要抓取它以完成 TableA 中的记录。我正在使用一个 ID 来引用从 TableB 中获取的地址。

a_h*_*ame 7

您不需要将值传递给触发器。触发器可以通过隐式记录完全访问插入行中的所有列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;
Run Code Online (Sandbox Code Playgroud)

但是,您不能更改after触发器中插入的行,您需要一个before触发器:

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

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


与你的问题无关,但你真的应该避免那些可怕的引用标识符。他们的麻烦比他们值得