插入后PostgreSQL触发函数更新
Posted
技术标签:
【中文标题】插入后PostgreSQL触发函数更新【英文标题】:PosgreSQL trigger function update after insert 【发布时间】:2020-02-08 10:15:19 【问题描述】:我是 PosgreSQL 触发器的新手。根据文档,我试图制作触发功能,但它不起作用,也不知道为什么。 有一个抓取插入到我的房地产数据库记录中。我想根据选定的条件更新新插入的记录。 这是我的触发功能代码:
CREATE OR REPLACE FUNCTION czynsz_clear() RETURNS TRIGGER AS $body$
BEGIN
IF administrative_fees IS NOT NULL
AND administrative_fees_m2 IS NULL
AND area IS NOT NULL
AND type_id IN (6,1)
AND administrative_fees > 1 AND area > 1
THEN
UPDATE realestates_realestate SET administrative_fees_m2 = TRUNC((administrative_fees/ AREA):: INTEGER,2)
RETURN NEW;
END IF;
END;
$body$ LANGUAGE plpgsql;
所以逻辑是: 将新记录插入数据库 realestates_realestate 后,我想检查所选字段是否为空或其他条件,然后进行更新。 创建函数后,我想在插入表后触发触发器启动此函数。
我做错了什么?我正在使用 HeidiSQL (10.3.0.5771) 并出现消息:
错误:在 RETURN 附近出现语法错误。第 11 行:返回新的;
删除这个RETURN NEW后,出现错误END IF;和相同的消息。
【问题讨论】:
【参考方案1】:如果要更改刚刚插入的行,请不要使用UPDATE
将值分配给字段或新记录。
要访问列值,也可以使用new
记录。
类似这样的:
CREATE OR REPLACE FUNCTION czynsz_clear()
RETURNS TRIGGER
AS $body$
BEGIN
if new.administrative_fees IS NOT NULL
AND new.administrative_fees_m2 IS NULL
AND new.area IS NOT NULL
AND new.type_id IN (6,1)
AND new.administrative_fees > 1
AND new.area > 1
THEN
new.administrative_fees_m2 := TRUNC((administrative_fees/ AREA)::INTEGER,2);
END IF;
RETURN NEW; -- this needs to be outside of the IF
END;
$body$ LANGUAGE plpgsql;
这假定触发器被定义为行级触发器,例如
您还需要将其设为 BEFORE 触发器
create trigger ..
BEFORE INSERT OR UPDATE on ....
FOR EACH ROW execute procedure czynsz_clear();
您遇到的错误是由于您的 UPDATE 语句没有以 ;
结尾的事实引起的。但即使在修复它之后,您也会收到错误,因为列名(在IF
部分中)不能像那样引用。
最后,触发器只有在IF
条件为真的情况下才会起作用,否则触发器将不会返回任何内容。所以return new;
需要在IF
语句之外。
【讨论】:
非常感谢!它有效,还需要在顶部添加 DELIMITER $$。我创建了触发器:create TRIGGER clear_czynsz_trigger AFTER INSERT OR UPDATE ON realestates_realestate FOR EACH ROW 执行过程 czynsz_clear();从逻辑上讲,它应该适用于我所在行所做的任何更新。我已经对此行的另一列进行了更新,只是为了检查它是否有效,并且没有更新我的管理费用行。为什么?我应该在插入还是更新之前制作? 是的,如果要更改行,则必须使用BEFORE
触发器。不知道DELIMITER $$
不是标准的 Postgres 命令是什么意思
当我尝试使用与上面完全相同的代码时,出现错误:'ERROR: unterminated dollar-quoted string at or near "$body$ BEGIN'。我看到有人已经问过这个问题并添加此作品。
这必须是特定于您的 SQL 客户端的内容。
是的,它是 Heidi :( 再次非常感谢。我已经检查过了,当我将“after”替换为“before”以进行更新时,它可以工作。我还指定了要应用的列对于更新,所以不会在刚刚指定的所有列的每次更新时启动。现在我只是在想,我可以将所有条件从函数移动到使用条件何时触发吗?在这种情况下,我应该使用: -- WHEN OLD。 Administrative_fees_m2 为 NULL 或 WHEN new.administrative_fees_m2 为 NULL?以上是关于插入后PostgreSQL触发函数更新的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个 Postgres 11 触发器函数,该函数在插入或更新到表“a”时在表“b”中插入一个新行?
Postgres SQL 触发器在 TableB 上插入或更新后使用新值更新 TableA.column