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

时间:2015-04-09 18:35:19

标签: postgresql triggers plpgsql dynamic-sql

我编写了一个触发函数,希望迭代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语句来检查每一列,但我更喜欢这个函数是通用的,所以我可以在将来将它用于其他表。

1 个答案:

答案 0 :(得分:1)

简单案例的静态代码

对于一堆给定的列我只想拼出来。

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 
WHEN ('{x:Null}' IN (NEW.val1, NEW.val2, NEW.val3))
EXECUTE PROCEDURE fix_nulls();

动态代码

如果许多列或(更好的理由)列(名称)发生了很大变化,则可能需要采用动态方法。但是,虽然plpgsql FOR循环可以遍历集合(表格)中的行或数组中的元素,但它可以 对行中的列执行相同操作 为什么呢?