触发器返回新的无限循环


CREATE OR REPLACE FUNCTION updatepersonne()
  RETURNS trigger AS
$BODY$
DECLARE 
IDToInsert numeric;
BEGIN
    SELECT "PersonneID" FROM "Personne" p INTO IDToInsert WHERE (p."Prenom"=NEW."Prenom" AND p."Nom"=NEW."Nom" AND p."Adresse"=NEW."Adresse");
IF IDToInsert IS NULL THEN
    INSERT INTO "Personne" ("PersonneID","Nom","Prenom","Adresse") VALUES (Default, NEW."Nom",NEW."Prenom",NEW."Adresse") RETURNING "PersonneID" into IDToInsert;
END IF;
NEW."PersonneID":=IDToInsert;
--IF TG_RELNAME="Emprunteur" 
--THEN
--  NEW."EmprunteurID":=IDToInsert;
--ELSE
--  NEW."DetenteurID":=IDToInsert;
--END IF;
return new;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION updatepersonne()
  OWNER TO postgres;
CREATE TRIGGER updatepersonnefromemprunteur
  BEFORE INSERT
  ON "Emprunteur"
  FOR EACH ROW
  EXECUTE PROCEDURE updatepersonne();

我想检查另一个表上是否存在元组,以便获取 ID 并将其用于新元组,或者如果不存在,则将其插入另一个表。它似乎获取了 ID 或将其正确插入到另一个表上(使用 return null 进行测试(,但主插入(在触发该事物的表上(进行了疯狂的无限循环。对不起,我的英语/表达能力很差。有什么提示吗?提前谢谢。

我有一些关于如何改进功能的提示。但是这里没有什么会导致无限循环。原因必须是问题中没有的内容,例如任何涉及表上的其他触发器或规则。

提示:

CREATE OR REPLACE FUNCTION updatepersonne()
  RETURNS trigger AS
$func$
BEGIN
WITH sel AS (
   SELECT "PersonneID"
   FROM   "Personne"
   WHERE  "Prenom"   = NEW."Prenom" 
   AND    "Nom"      = NEW."Nom"
   AND    "Adresse" = NEW."Adresse"
   )
   , ins AS (
    INSERT INTO "Personne" ("Nom", "Prenom", "Adresse")
    SELECT (NEW."Nom", NEW."Prenom", NEW."Adresse")
    WHERE  NOT EXISTS (SELECT 1 FROM sel)
    RETURNING "PersonneID"
   )
SELECT COALESCE(sel."PersonneID", ins."PersonneID")
FROM   ins, sel
INTO   NEW."PersonneID";
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER updatepersonnefromemprunteur
  BEFORE INSERT
  ON "Emprunteur"
  FOR EACH ROW
  EXECUTE PROCEDURE updatepersonne();
  • 使用数据修改 CTE 最小化 SELECT 和 INSERT 之间的时间窗口,以避免并发负载过重时可能出现的争用情况。更多关于这一点:
    函数中的 SELECT 或 INSERT 是否容易出现竞争条件?

  • 无需声明其他变量,可以直接选择 into NEW."PersonneID"

  • 要将默认值插入新行的列中,只需从INSERT中省略该列。

最新更新