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进行测试)但是主插入(在触发该事物的表上)继续进行疯狂的无限循环。 抱歉我的英语/表达能力差。 任何提示?事先确定。
答案 0 :(得分:1)
我有一些关于如何改进功能的提示。但这里没有什么会导致无限循环。原因必须是问题中不存在的问题,例如任何相关表格上的其他触发器或规则。
提示:
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之间的时间窗口,以避免可能的竞争条件和大量并发负载。更多内容:
Is SELECT or INSERT in a function prone to race conditions?
您无需声明其他变量,可以直接选择NEW."PersonneID"
。
要将默认值插入新行的列中,只需忽略INSERT
中的列。