如何在 PostgreSQL/PostGIS 中的 INSERT 触发器后更新表的新值?
How to update the tables NEW values after INSERT Trigger in PostgreSQL/PostGIS?
我尝试在我的数据库中对 table 进行一些计算自动化。我尝试对 table 中新插入的行执行一些 UPDATE
,但我以前使用过 NEW
或 OLD
语句。我尝试编写通过分配 NEW.[tablename]
对新值进行更新的代码,但它不起作用。触发器函数的开头是否有任何语句指定 运行 仅在新值上使用该函数,我找不到有关此的有用信息。
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
DECLARE
a INTEGER := 3;
BEGIN
UPDATE NEW.cost_table
SET column4 = a;
UPDATE NEW.cost_table
SET column 5 = column4 - column2;
[...]
RETURN NEW;
END
$func$ language plpgsql
更新:
感谢您到目前为止的回答。
我原来的代码是基于update结构写的,省略UPDATE
时需要重写。我应该举一个更好的例子来说明我的情况。简单地说:我有一个 table (T1),它将被另一个 table (T2) 的数据填充。
将数据从 T2 插入 T1 后,我想 运行 对 T1 内部的新值进行计算。(代码包括 PostGIS 功能):
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
BEGIN
NEW.column6 = column2 FROM external_table WHERE
St_Intersects(NEW.geom, external_table.geom) LIMIT1;
NEW.column8 = CASE
WHEN st_intersects(NEW.geom, external_table2.geom) then 'intersects'
WHEN (NEW.column9 = 'K' and NEW.column10 <= 6) then 'somethingelse'
ELSE 'nothing'
END
FROM external_table2;
[...]
RETURN NEW;
END
$func$ language plpgsql
CREATE TRIGGER table_calculation_on_new
BEFORE INSERT OR UPDATE ON cost_estimation
FOR EACH ROW EXECUTE PROCEDURE road_coast_estimation();
在我的 table 中插入值后,将不会执行任何计算。
更新 2:我再次检查了我的 tables 并检测到另一个触发器正在阻止 table 操作。由于@a_horse_with_no_name.
,下半部分的代码现在可以正常工作了
NEW
和 OLD
不是“语句”,它们是 records,表示触发触发器的 DML 语句中的修改行。
假设触发器是在 cost_table
上定义的,您可以简单地更改 NEW
记录中的字段。无需更新任何内容:
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
DECLARE
a INTEGER := 3;
BEGIN
new.column4 := a;
new.column5 := new.column4 - new.column2;
return new;
END;
$func$ language plpgsql
为此,需要将触发器定义为 BEFORE
触发器:
create trigger cost_table_trigger
BEFORE insert or update on cost_table
for each row execute procedure cost_estimation();
我尝试在我的数据库中对 table 进行一些计算自动化。我尝试对 table 中新插入的行执行一些 UPDATE
,但我以前使用过 NEW
或 OLD
语句。我尝试编写通过分配 NEW.[tablename]
对新值进行更新的代码,但它不起作用。触发器函数的开头是否有任何语句指定 运行 仅在新值上使用该函数,我找不到有关此的有用信息。
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
DECLARE
a INTEGER := 3;
BEGIN
UPDATE NEW.cost_table
SET column4 = a;
UPDATE NEW.cost_table
SET column 5 = column4 - column2;
[...]
RETURN NEW;
END
$func$ language plpgsql
更新:
感谢您到目前为止的回答。
我原来的代码是基于update结构写的,省略UPDATE
时需要重写。我应该举一个更好的例子来说明我的情况。简单地说:我有一个 table (T1),它将被另一个 table (T2) 的数据填充。
将数据从 T2 插入 T1 后,我想 运行 对 T1 内部的新值进行计算。(代码包括 PostGIS 功能):
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
BEGIN
NEW.column6 = column2 FROM external_table WHERE
St_Intersects(NEW.geom, external_table.geom) LIMIT1;
NEW.column8 = CASE
WHEN st_intersects(NEW.geom, external_table2.geom) then 'intersects'
WHEN (NEW.column9 = 'K' and NEW.column10 <= 6) then 'somethingelse'
ELSE 'nothing'
END
FROM external_table2;
[...]
RETURN NEW;
END
$func$ language plpgsql
CREATE TRIGGER table_calculation_on_new
BEFORE INSERT OR UPDATE ON cost_estimation
FOR EACH ROW EXECUTE PROCEDURE road_coast_estimation();
在我的 table 中插入值后,将不会执行任何计算。
更新 2:我再次检查了我的 tables 并检测到另一个触发器正在阻止 table 操作。由于@a_horse_with_no_name.
,下半部分的代码现在可以正常工作了NEW
和 OLD
不是“语句”,它们是 records,表示触发触发器的 DML 语句中的修改行。
假设触发器是在 cost_table
上定义的,您可以简单地更改 NEW
记录中的字段。无需更新任何内容:
CREATE OR REPLACE FUNCTION cost_estimation()
RETURNS TRIGGER AS
$func$
DECLARE
a INTEGER := 3;
BEGIN
new.column4 := a;
new.column5 := new.column4 - new.column2;
return new;
END;
$func$ language plpgsql
为此,需要将触发器定义为 BEFORE
触发器:
create trigger cost_table_trigger BEFORE insert or update on cost_table for each row execute procedure cost_estimation();