postgres子字符串触发问题

postgres substring trigger issue

在 postgres 触发器中使用子字符串时遇到问题 这是我使用的触发器

CREATE FUNCTION TRIGGER1() RETURNS trigger AS $autouuid$
BEGIN

    update test_points.scada_rtu i
    set dummy #field_name
    = upper(substr (NEW.city_name, 1, 2) || right (NEW.city_name, 1) || '-' || substr  (NEW.phase_name, 1, 2) || right (NEW.phase_name, 1) || '-' || substr (NEW.area_name, 1, 3) || '-' || 
            substr(NEW.name, 1, 2) || right (NEW.name, 1) || '-' || substr (NEW.rtu_model, 1, 2) || right (NEW.rtu_model, 1)) 
    WHERE i.id = OLD.id;
    RETURN NEW;
END;
$autouuid$ LANGUAGE plpgsql;
CREATE TRIGGER autouuid_update BEFORE INSERT OR UPDATE ON test_points.scada_rtu
    FOR EACH ROW
EXECUTE PROCEDURE public.TRIGGER1();

error message

CREATE FUNCTION TRIGGER1() RETURNS trigger AS $autouuid$
BEGIN
    NEW.dummy=upper(
                concat_ws('-',
                    regexp_replace(NEW.city_name,   '^(..).*(.)$',  ''),
                    regexp_replace(NEW.phase_name,  '^(..).*(.)$',  ''),
                    regexp_replace(NEW.name,        '^(..).*(.)$',  ''), 
                    regexp_replace(NEW.rtu_model,   '^(..).*(.)$',  '')
                )
              ); 
    RETURN NEW;
END;
$autouuid$ LANGUAGE plpgsql;
CREATE TRIGGER autouuid_update BEFORE INSERT OR UPDATE ON test_points.scada_rtu
    FOR EACH ROW
EXECUTE PROCEDURE public.TRIGGER1();
  1. 正如 @a_horse_with_no_name 所指出的,您可以直接将新值分配给 NEW 记录,而无需发布新的更新。
  2. @Frank Heikens 所述,从更新时触发的函数发出新更新会使它调用自身,使您陷入无限循环。
  3. 直接赋值给record-type variable NEW will solve your problem, because it'll operate within trigger's context where trigger's special variables are visible. Your error is caused by the fact your update query thinks it's a reference to one of the target table's columns, ignoring the variable. @Adrian Klaver
  4. 您无需每次使用||重复连接和手动添加分隔符。 concat_ws() 为您完成这两件事,同时忽略 NULL 值。
  5. 获取字符串的前两个字符和最后一个字符也可以使用单个 regexp_replace().
  6. #comment 不是有效的 PL/pgSQL 评论。使用 --comment 表示单行行尾或 /*comment*/ 表示多行、中行注释。您的评论将与函数定义一起保存,并在有人查找时可见。