单行列字段的 Postgresql 触发器
Posted
技术标签:
【中文标题】单行列字段的 Postgresql 触发器【英文标题】:Postgresql Trigger for a Single Row Column Field 【发布时间】:2018-03-27 17:09:02 【问题描述】:我需要一些帮助来修复我的 Postgres 9.4 表触发器配置。在过去的几天里,我一直在尝试几种不同的 *** 搜索想法,但都没有成功。如何修复我的代码以满足下面描述的简单要求?
要求是根据当前总线状态字段值更改颜色字段状态。颜色更新应该只发生在单行而不是整个 BusColor 表中。因此,当 AI_Bus ‘1145’ 操作状态 (BusStatus) 为 INSERT 或 UPDATED 时,触发器会将颜色字段更改为正确的关联颜色。假设“1145”的 BusStatus 从“NSCH”更新为“SCH”,那么触发器会将颜色值从“白色”更改为“黄色”。以下是我的 Posgresql 9.4 对象配置:
CREATE TABLE BusColor (
AI_Bus serial PRIMARY KEY,
BusStatus character varying NOT NULL,
color character varying NOT NULL );
SELECT * FROM “MyDB”.”BusColor”;
AI_Bus BusStatus color
1145 NSCH white
1146 SCH yellow
1147 NSCH white
1148 OPER green
CREATE TRIGGER “UpdateBusColor” BEFORE INSERT OR UPDATE ON “BusColor”
FOR EACH STATEMENT EXECUTE PROCEDURE “TrigFuncBusColor”();
CREATE FUNCTION “TrigFuncBusColor”() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
IF (TG_OP = ‘UPDATE’) THEN
IF (NEW.”BusStatus” <> OLD.”BusStatus”) THEN
IF NEW.“BusStatus” = ‘NSCH’ THEN
UPDATE “MyDB”.”BusColor” SET “color” = ‘white’;
RETURN NEW;
END IF;
IF NEW.“BusStatus” = ‘SCH’ THEN
UPDATE “MyDB”.”BusColor” SET “color” = ‘yellow’;
RETURN NEW;
END IF;
IF NEW.“ID_BusStatus” = ‘OPER’ THEN
UPDATE “MyDB”.”BusColor” SET “color” = ‘green’;
RETURN NEW;
END IF;
END IF;
END IF;
RETURN NULL;
END;
$$;
【问题讨论】:
您理解触发器更新错误,而不是使用update set ....
命令,您只需为新字段设置值,例如NEW.color = 'somevalue'
我刚刚尝试使用 UPDATE 语句,因为 NEW & OLD 产生错误:尚未分配记录“new”。元组结构未分配记录是不确定的。这对我来说就像是第 50 版......尝试了互联网上所有疯狂的东西。
将触发器从FOR EACH STATEMENT
更改为FOR EACH ROW
并使用NEW.field
谢谢豪尔赫!我切换回FOR EACH ROW
并将更新字段改回原来的。 CREATE TRIGGER “UpdateBusColor4” BEFORE INSERT OR UPDATE OF “BusStatus”, color ON “BusColor” FOR EACH ROW EXECUTE PROCEDURE “TrigFuncBusColor”();
我也改了触发功能:CREATE FUNCTION “TrigFuncBusColor”() RETURNS trigger LANGUAGE plpgsql AS $$BEGIN IF TG_OP = ‘UPDATE’ THEN IF (OLD.”BusStatus” <> NEW .”BusStatus”) THEN IF (NEW.“BusStatus” = ‘SCH’) THEN NEW.“color” = ‘yellow’; RETURN NEW; END IF; IF (NEW.“BusStatus” = ‘NSCH’) THEN NEW.“color” = ‘white’; RETURN NEW; END IF; IF (NEW.“BusStatus” = ‘OPER’) THEN NEW.“color” = ‘green’; RETURN NEW; END IF; END IF; END IF; RETURN NULL; END; $$;
【参考方案1】:
为什么要为每个总线状态使用条件,只需选择替换状态的颜色并更新所有状态的颜色是新的。
CREATE FUNCTION “TrigFuncBusColor”() RETURNS trigger
LANGUAGE plpgsql
declare newColor varchar;
AS $$BEGIN
IF (TG_OP = ‘UPDATE’) THEN
IF (NEW.”BusStatus” <> OLD.”BusStatus”) THEN
SELECT "color" INTO newColor FROM “MyDB”.”BusColor” WHERE BusStatus = NEW.“BusStatus” LIMIT 1;
UPDATE “MyDB”.”BusColor” SET “color” = newColor where BusStatus = NEW.“BusStatus”;
RETURN NEW;
END IF;
END IF;
RETURN NULL;
END;
【讨论】:
以上是关于单行列字段的 Postgresql 触发器的主要内容,如果未能解决你的问题,请参考以下文章