PostgreSQL 函数和触发器在 postgresql 中包含更改
Posted
技术标签:
【中文标题】PostgreSQL 函数和触发器在 postgresql 中包含更改【英文标题】:PostgreSQL Function and trigger in postresql to contain changes 【发布时间】:2021-11-26 16:50:44 【问题描述】:我想实现一个函数和一个触发器(不带参数),只要它们在表 D 中进行,就允许在表 B 中进行更改。我所说的更改是插入、更新或删除。
例如,如果我在表 D 中删除、更新或插入一条记录,我需要它也在表 B 中自动完成,并将添加的新值返回给我。
我已经设计了这个表 D,它有一个主键,它由从其他表(表 A、表 C 和表 D)获得的 3 个值组成。
例如我有;
TABLE A
x int (primary key)
y character
z character
TABLE C
a int (primary key)
b character
c character
TABLE D
x (primary key)
a (primary key)
dd (primary key)
ddd
dddd
TABLE B
x (primary key)
a (primary key)
dd (primary key)
bbb
bbbb
结构应该类似于以下内容。曾想过在几个IF的函数中实现几个TG_OP,但都没有得到满意的结果。
CREATE FUNCTION function()
RETURNS trigger language plpgsql AS $$
BEGIN
RETURN new;
END;
$$;
CREATE TRIGGER trigger
AFTER UPDATE ON table D
FOR EACH ROW EXECUTE PROCEDURE function();
谢谢大家
【问题讨论】:
为什么你有两个表,如果它们都有相同的内容?更简单的方法是创建像CREATE VIEW B AS SELECT * FROM D;
这样的视图
嗯,它们没有相同的功能。实际上,它们具有相同的复合主键,但具有不同的属性。
这闻起来就像将字段 bbb
和 bbbb
添加到表 D(或 ddd
和 dddd
到表 B)也是一个解决方案?
我同意@Luuk 的观点,因为这可以通过使用带有ON DELETE CASCADE ON UPDATE CASCADE
的视图和/或外键以更简单的方式实现,如果在代码和主键定义在末尾移到了constraint pkey primary key (x,a,dd)
]。
【参考方案1】:
您需要为表 D 上的 INSERT、UPDATE、DELETE 创建 3 个分隔的 trigger functions
:
CREATE FUNCTION tableD_insert()
RETURNS trigger language plpgsql AS $$
BEGIN
INSERT INTO tableB (x, a, dd) VALUES (NEW.x, NEW.a, NEW.dd) ; -- all the other columns of tableB will be empty or automatically fulfilled with their default values
RETURN new;
END;
$$;
CREATE TRIGGER tableD_insert
AFTER INSERT ON tableD
FOR EACH ROW EXECUTE PROCEDURE tableD_insert();
CREATE FUNCTION tableD_update()
RETURNS trigger language plpgsql AS $$
BEGIN
UPDATE tableB
SET x = NEW.x, a = NEW.a, dd = NEW.dd
WHERE x = OLD.x AND a = OLD.a AND dd = OLD.dd ;
RETURN new;
END;
$$;
CREATE TRIGGER tableD_update
AFTER UPDATE ON table D OF x, a, dd
FOR EACH ROW EXECUTE PROCEDURE tableD_update();
CREATE FUNCTION tableD_delete()
RETURNS trigger language plpgsql AS $$
BEGIN
DELETE FROM tableB
WHERE x = OLD.x AND a = OLD.a AND dd = OLD.dd ;
RETURN old;
END;
$$;
CREATE TRIGGER tableD_delete
AFTER DELETE ON tableD
FOR EACH ROW EXECUTE PROCEDURE tableD_delete();
【讨论】:
你好爱德华!谢谢您的答复。有没有办法以更压缩的形式做到这一点? 不行,sql语句各不相同,必须关联rigth trigger。 @yuda 这实际上非常少,这里只有 3 行实际逻辑。其余的只是将逻辑放在正确位置所需的必要语法,并格式化以提高可读性。以上是关于PostgreSQL 函数和触发器在 postgresql 中包含更改的主要内容,如果未能解决你的问题,请参考以下文章