情况:
我有一个fn_SetFoo()
将记录插入表的函数TableFoo
。
我还有一个触发功能,在每次插入TableFoo
. 它TableFooID
从新插入的行中获取新的主键并将其插入到第二个表中TableFooBar
(具有外键约束)。
我创建了一个运行的触发器AFTER INSERT ON TableFoo FOR EACH ROW EXECUTE PROCEDURE fn_SetFooBar();
如果我fn_SetFoo()
直接打电话,那么一切都会按预期进行。
但是,我有一个单独的函数fn_NormalizeFoo()
来处理一些数据,然后调用fn_SetFoo()
它处理的每条记录。
如果我打电话fn_NormalizeFoo()
,那么只有第一条记录被处理并且函数停止。
问题:
为什么直接fn_NormalizeFoo()
运行的内容在整个进程运行时调用时,进程会在第一条记录后停止?fn_NormalizeFoo()
一些代码:
--------------------------------------------------------
-- Insert Into TableFoo --
--------------------------------------------------------
CREATE OR REPLACE FUNCTION "example"."fn_SetFoo" (
IN "Foo1" INTEGER,
IN "Foo2" INTEGER,
IN "Foo3" INTEGER
) RETURNS "void" AS
$$
BEGIN
INSERT INTO
"example"."TableFoo"(
"Foo1",
"Foo2",
"Foo3"
)
VALUES
(
$1,
$2,
$3
);
RETURN;
EXCEPTION WHEN "unique_violation" THEN
-- DO NOTHING
END;
$$
LANGUAGE plpgsql;
--------------------------------------------------------
-- Insert Into TableFooBar --
--------------------------------------------------------
CREATE OR REPLACE FUNCTION "example"."fn_SetFooBar" (
IN "FooPK" INTEGER,
IN "BarPK" INTEGER
) RETURNS "void" AS
$$
BEGIN
INSERT INTO
"example"."TableFooBar"(
"FooPK",
"BarPK"
)
VALUES
(
$1,
$2
);
RETURN;
EXCEPTION WHEN "unique_violation" THEN
-- DO NOTHING
END;
$$
LANGUAGE plpgsql;
--------------------------------------------------------
-- Trigger Function --
--------------------------------------------------------
CREATE OR REPLACE FUNCTION "example"."tr_SetFooBar"() RETURNS TRIGGER AS
$$
BEGIN
PERFORM
"example"."fn_SetFooBar"(
"TableFoo"."FooPK",
"TableBar"."BarPK"
)
FROM
"example"."TableFoo" JOIN
"example"."TableBar" ON [SOMETHING TRUE]
WHERE
NEW.SOMECOLUMN = SOMETHING AND
[MORE STUFF IS TRUE];
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
--------------------------------------------------------
-- Trigger --
--------------------------------------------------------
CREATE TRIGGER "SetFooBar" AFTER INSERT ON "example"."Foo" FOR EACH ROW EXECUTE PROCEDURE "example"."tr_SetFooBar"();
--------------------------------------------------------
-- Normalize Foo --
--------------------------------------------------------
CREATE OR REPLACE FUNCTION "example"."fn_NormaliseFoo" (
IN "Param1" VARCHAR,
IN "Param2" VARCHAR,
IN "Param3" VARCHAR
) RETURNS "void" AS
$$
SELECT
"example"."fn_SetFoo" (
"Foo1",
"Foo2",
"Foo3"
)
FROM
[TABLES]
WHERE
[STUFF IS TRUE]
$$
LANGUAGE SQL;
如您所见,这比我最初发布的要复杂一些。总体思路是在添加每条记录时创建多对多关系。
重申一下,"example"."fn_NormaliseFoo"
在第一行之后运行失败;但是,手动运行内容按预期工作。