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; 这样的视图 嗯,它们没有相同的功能。实际上,它们具有相同的复合主键,但具有不同的属性。 这闻起来就像将字段 bbbbbbb 添加到表 D(或 ddddddd 到表 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 中包含更改的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 9.3 触发函数以参数化名称插入表

postgrey9.5哪年

如何查看本地安装的Postgresql版本号

何为PostgreSQL?

Postgres-XL:JSON 函数

PostgreSQL新手入门