我可以在 PostgreSQL 触发器函数中迭代 NEW 吗?

Can I iterate over NEW in a PostgreSQL trigger function?

我写了一个触发器函数,希望遍历 NEW 并检查它的所有值。

CREATE OR REPLACE FUNCTION fix_nulls() RETURNS TRIGGER AS $_$
BEGIN
    FOR val IN NEW
    LOOP
        IF val = '{x:Null}'
            val := '';
        ENDIF;      
    ENDLOOP;
    RETURN NEW;
END $_$ LANGUAGE 'plpgsql';

CREATE TRIGGER prevent_nulls_siteinfo
    BEFORE UPDATE OR INSERT ON siteinfo
    FOR EACH ROW
    EXECUTE PROCEDURE fix_nulls();

但我收到语法错误:

ERROR:  syntax error at or near "NEW"
LINE 3:  FOR val IN NEW
                    ^

是否可以遍历 NEW 中的所有值?我可以轻松地编写一堆 if 语句来检查每一列,但我更希望这个函数是通用的,这样我将来可以将它用于其他表。

简单案例的静态代码

对于一些给定的专栏,我会拼写出来。

CREATE OR REPLACE FUNCTION fix_nulls()
  RETURNS TRIGGER AS
$func$
BEGIN
   IF NEW.val1 = '{x:Null}' THEN NEW.val1 := ''; END IF;
   IF NEW.val2 = '{x:Null}' THEN NEW.val2 := ''; END IF;
   IF NEW.va31 = '{x:Null}' THEN NEW.val3 := ''; END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;
  • 不要引用语言名称plpgsql,它是一个标识符。

并且只在相关时触发触发器:

CREATE TRIGGER prevent_nulls_siteinfo
BEFORE UPDATE OR INSERT ON siteinfo
FOR EACH ROW 
<b>WHEN ('{x:Null}' IN (NEW.val1, NEW.val2, NEW.val3))</b>
EXECUTE PROCEDURE fix_nulls();

动态代码

如果有许多 列或(更好的理由)列(名称)变化很大,可能需要动态方法。但是,虽然 plpgsql FOR 循环可以迭代集合中的 行 (table) 或数组中的 元素 , 它可以 而不是 对连续的列执行相同的操作。
为什么?

  • PL/pgSQL: General Way to Update N Columns in Trigger?