在触发器中循环

时间:2013-05-12 11:59:51

标签: postgresql triggers

我有这样的表

 id | col1 | col2

我需要写入触发器,因此:在插入或更新列col1后,我需要在col2列中插入(更新)相同的值

这是我的触发功能:

CREATE FUNCTION  upd () RETURNS TRIGGER AS '
   BEGIN 
       UPDATE mytable SET
       col2 =  col1;
       RETURN NULL;
   END;
'
LANGUAGE plpgsql;

这是自触发的:

CREATE TRIGGER upd_trigger
AFTER INSERT OR UPDATE ON mytable
FOR EACH ROW
EXECUTE PROCEDURE upd()

这不起作用,因为在UPDATE事件中发生了旋风,对吧?

这样做的正确语法是什么?

3 个答案:

答案 0 :(得分:1)

您不需要更新,只需指定值:

CREATE FUNCTION  upd () RETURNS TRIGGER AS 
$body$
   BEGIN 
      new.col2 := to_tsvector(new.col1);
      RETURN new;
   END;
$body$
LANGUAGE plpgsql;

您需要在之前触发器中执行此操作:

CREATE TRIGGER upd_trigger
BEFORE INSERT OR UPDATE ON mytable
FOR EACH ROW
EXECUTE PROCEDURE upd()

修改

正如@DavidAldridge在他的评论中指出的那样,直接索引ts_vector()可能更容易:

create index col1_vector 
    on mytable (to_tsvector(col1)) 
    using gin;

使用

进行查询
where to_tsvector(col1) = '...'
然后

就可以使用该索引。

答案 1 :(得分:1)

@a_horse和@David已经为您的案例指出了具有GIN索引的优秀解决方案。

但是对于原始问题的答案还有一件事:由于您只需要触发器after inserting or updating column col1,因此您应该使用自Postgres 9.0以来可用的更具体的事件UPDATE OF ...

CREATE TRIGGER upd_trigger
BEFORE INSERT OR UPDATE OF col1 ON mytable
FOR EACH ROW
EXECUTE PROCEDURE upd()

这样你甚至可以在AFTER触发器中阻止无限循环/递归(在你调用它时“循环”)。但是使用BEFORE触发器通常更明智,比如已经提供的@a_horse。

答案 2 :(得分:0)

如果col2的值确定性地仅依赖于col1的值,那么col2就不应该存储。