如何创建一个 Postgres 11 触发器函数,该函数在插入或更新到表“a”时在表“b”中插入一个新行?
Posted
技术标签:
【中文标题】如何创建一个 Postgres 11 触发器函数,该函数在插入或更新到表“a”时在表“b”中插入一个新行?【英文标题】:How can I create a Postgres 11 trigger function which inserts a new row in table 'b' upon insert or update to table 'a'? 【发布时间】:2021-02-03 23:49:48 【问题描述】:我在 RDS 上运行 Postgres 11。 我正在尝试创建一个简单的触发器函数,以便在将行插入表“test_values”时将记录插入表“test_alias”。
我有以下表格:
CREATE TABLE the_schema.test_values (
id INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
value_1 TEXT NOT NULL,
value_2 TEXT NOT NULL,
value_quantity INTEGER NOT NULL
);
CREATE TABLE the_schema.test_alias (
id INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
value_1_copy TEXT NOT NULL,
value_2_copy TEXT NOT NULL,
value_quantity_copy INTEGER NOT NULL
);
我的触发函数是这样的:
CREATE OR REPLACE FUNCTION the_schema.populate_test_alias()
RETURNS TRIGGER AS
$BODY$
BEGIN
IF NEW.the_schema.test_values THEN
INSERT INTO the_schema.test_alias (value_1_copy, value_2_copy, value_quantity_copy)
VALUES (NEW.value_1, NEW.value_2, NEW.value_quantity);
END IF;
return null;
END;
$BODY$ LANGUAGE plpgsql;
这里是触发器:
CREATE TRIGGER TRG_TEST_ALIAS
AFTER INSERT OR UPDATE ON the_schema.test_values
FOR EACH ROW
execute procedure the_schema.populate_test_alias();
像这样插入:
INSERT INTO the_schema.test_values (value_1, value_2, value_quantity)
VALUES ('abc', 'xyz', 1);
我收到此错误:
ERROR: missing FROM-clause entry for table "the_schema"
LINE 1: SELECT NEW.the_schema.test_values
我还尝试了使用默认架构的等效设置,但它仍然出错(尽管有不同的错误):
ERROR: record "new" has no field "test_values"
CONTEXT: SQL statement "SELECT NEW.test_values"
PL/pgSQL function populate_test_alias() line 3 at IF
在我看来,我使用 NEW 关键字的方式一定有错误,但据我所知,我在函数中使用它的方式与我的几个示例相同'已经提到(在线/SO 和硬拷贝),我想不通。
非常感谢所有指导!
类似问题的示例供参考,包括官方文档的链接(我也读过,但显然不明白我应该理解): [https://***.com/questions/11001118/postgres-trigger-after-insert-accessing-new]
【问题讨论】:
这个IF NEW.the_schema.test_values THEN
应该测试什么? NEW 引用插入的行。
好问题!我从教程中复制了它,但现在你提到它,它似乎是多余的——让我尝试不使用条件——编辑:删除if
语句后,我收到以下错误:ERROR: record "new" has no field "test_values" CONTEXT: SQL statement "SELECT NEW.test_values" PL/pgSQL function populate_test_alias() line 3 at IF
删除整行 - 显然还有 END iF。
很好,成功了!感谢您的帮助,我非常感谢!
【参考方案1】:
NEW
引用插入或更新的行。因此NEW.
只对字段标识符有意义。
还有value_1, value_2
和value_quantity
有一个NOT NULL
约束,这意味着您不需要测试它们。
所以你可以放弃整个条件:
CREATE OR REPLACE FUNCTION the_schema.populate_test_alias()
RETURNS TRIGGER AS
$BODY$
BEGIN
--IF NEW.the_schema.test_values THEN
INSERT INTO the_schema.test_alias (value_1_copy, value_2_copy, value_quantity_copy)
VALUES (NEW.value_1, NEW.value_2, NEW.value_quantity);
--END IF;
return null;
END;
$BODY$ LANGUAGE plpgsql;
【讨论】:
以上是关于如何创建一个 Postgres 11 触发器函数,该函数在插入或更新到表“a”时在表“b”中插入一个新行?的主要内容,如果未能解决你的问题,请参考以下文章
postgres 触发器创建索引:BEFORE INSERT ON 隐藏一行
在 Postgres 上使用 pl/Python 创建触发器
如何使用 Postgres 和 GraphQL 在特定日期自动触发事件?