代码之家  ›  专栏  ›  技术社区  ›  MD Sayem Ahmed

是否可以动态循环表的列?

  •  5
  • MD Sayem Ahmed  · 技术社区  · 15 年前

    我有一个表测试的触发器函数,它有以下代码段:

    IF TG_OP='UPDATE' THEN
        IF OLD.locked > 0 AND
     (       OLD.org_id <> NEW.org_id OR
                OLD.document_code <> NEW.document_code OR
                -- other columns ...
     )
    THEN
        RAISE EXCEPTION 'Message';
    -- more code
    

    所以我静态地检查所有列的新值和它以前的值,以确保完整性。现在,每当我的业务逻辑发生变化并且必须向该表中添加新的列时,每次都必须修改这个触发器。我想如果我能动态地检查该表的所有列,而不显式地键入它们的名称,那就更好了。

    5 回复  |  直到 6 年前
        1
  •  11
  •   Frank Heikens    15 年前

    看一下信息模式,有一个视图“columns”。执行查询以从触发触发器的表中获取所有当前列名:

    SELECT 
        column_name 
    FROM 
        information_schema.columns 
    WHERE 
        table_schema = TG_TABLE_SCHEMA 
    AND 
        table_name = TG_TABLE_NAME;
    

    在结果中循环,就这样!

    更多信息可以在 fine manual .

        2
  •  11
  •   Stephen Denne    15 年前

    WHEN 触发器中的子句,可以在触发器体中的早期版本中使用:

    OLD.* IS DISTINCT FROM NEW.*

    或者有可能( from 8.2 release notes

    IF row(new.*) IS DISTINCT FROM row(old.*)

        4
  •  2
  •   Erwin Brandstetter    6 年前

    WHEN clause 你的触发定义( CREATE TRIGGER 声明):

    CREATE TRIGGER foo
    BEFORE UPDATE
    FOR EACH ROW
    WHEN (OLD IS DISTINCT FROM NEW)  -- parentheses required!
    EXECUTE PROCEDURE ...;
    

    仅适用于触发器 BEFORE / AFTER UPDATE ,其中 OLD NEW 定义了。你用这个会有个例外 带的子句 INSERT DELETE

    从根本上简化触发器 功能

    ...
    IF OLD.locked > 0 THEN
       RAISE EXCEPTION 'Message';
    END IF;
    ...
    

    无需测试 IF TG_OP='UPDATE' ... 更新

    CREATE TRIGGER foo
    BEFORE UPDATE
    FOR EACH ROW
    WHEN (OLD.locked > 0
      AND OLD IS DISTINCT FROM NEW)
    EXECUTE PROCEDURE ...;
    

    只留下一个无条件的 RAISE EXCEPTION 在触发器函数中,只有在需要时才调用。

    Read the fine print:

    在一个 之前 什么时候 条件是在 函数正在或将要执行,因此使用 什么时候 不是实质性的 触发功能。请特别注意 条件是当前值,可能由前面的 触发器 什么时候 检查的系统列 新建 oid ),因为那些

    在一个 之后 扳机,扳机 什么时候 行更新发生,它确定事件是否排队等待 在语句末尾触发触发器。所以当一个 之后 触发器 条件不返回true,不需要将 如果 触发器只需要为少数行触发。

    也要回答问题标题

    对。示例:

        5
  •  1
  •   user80168 user80168    15 年前

    许多的 更好。

    hstore-new ,并使用其行->hstore语义,但在使用普通数据类型时,这绝对不是一个好主意。