【发布时间】:2016-12-20 01:48:39
【问题描述】:
我有一个表 a,其中有 3 个触发器,每当插入、更新或删除 a 中的行时,它们会插入、更新或删除 b 中的相应行。所有 3 个触发器都使用相同的触发器函数p。
CREATE OR REPLACE FUNCTION p ()
RETURNS TRIGGER
AS $$
BEGIN
IF (TG_OP = 'INSERT') THEN
-- INSERT INTO b ...
RETURN NEW;
ELSIF (TG_OP = 'UPDATE') THEN
-- UPDATE b ...
RETURN NEW;
ELSIF (TG_OP = 'DELETE') THEN
-- DELETE FROM b ...
RETURN NEW;
ELSE
RETURN NULL;
END IF;
END;
$$ LANGUAGE PLPGSQL;
CREATE TRIGGER i AFTER INSERT ON a FOR EACH ROW EXECUTE PROCEDURE p ();
CREATE TRIGGER u AFTER UPDATE ON a FOR EACH ROW EXECUTE PROCEDURE p ();
CREATE TRIGGER d AFTER DELETE ON a FOR EACH ROW EXECUTE PROCEDURE p ();
a 也有一个外键 a1 到 c (主键 c1),我想改变 p 使其进入 IF/@987654332 @ 分支也取决于c 中的c2 列:如果该连接列发生更改,请输入INSERT 和UPDATE 分支;如果保持不变,请输入 UPDATE 分支。实际上,是这样的:
IF (TG_OP = 'INSERT') OR ((TG_OP = 'UPDATE') AND (oldC.c2 <> newC.c2)) THEN
-- ...
ELSIF (TG_OP = 'UPDATE') OR (oldC.c2 = newC.c2) THEN
-- ...
ELSIF (TG_OP = 'DELETE') OR ((TG_OP = 'UPDATE') AND (oldC.c2 <> newC.c2)) THEN
-- ...
ELSE
-- ...
END IF;
oldC 和 newC 将由类似于这些的连接产生(使用近似语法):
SELECT oldC.* FROM a, c AS oldC WHERE OLD.a1 = c.c1;
SELECT newC.* FROM a, c AS newC WHERE NEW.a1 = c.c1;
因此实际上需要在IF 语句之外进行两个连接,这将允许它引用oldC 和newC(或类似的东西)。这可能吗?p 的更改版本看起来如何(使用正确的 PostgreSQL 语法)?
【问题讨论】:
标签: postgresql join triggers plpgsql database-trigger