【问题标题】:How to avoid recursion in a trigger in PostgreSQL如何避免 PostgreSQL 触发器中的递归
【发布时间】:2015-08-01 19:50:27
【问题描述】:

我在触发器中遇到递归问题。

我有桌子:

CREATE TABLE employees(
   task int4 NOT NULL,
   first_name varchar(40) NOT NULL,
   last_name varchar(40) NOT NULL,
   PRIMARY KEY (task, cli_id_number)
);

当我插入值时:

(123, name, last)

我也想自动插入这些值:

(321, name, last)

我按以下方式执行此操作,但显然触发器是递归的,并且在第一次递归之后它会尝试插入先前插入的值。

CREATE OR REPLACE FUNCTION insert_task() RETURNS trigger AS $BODY$
BEGIN
  IF new.task = '123' AND (
     SELECT cant FROM (
       SELECT name, task, count(*) AS cant
       FROM client_task
       WHERE name = NEW.name AND task = NEW.task
       GOUP BY 1,2
       HAVING count(*) <= 1
     ) t) = 1 THEN
    INSERT INTO client_task(task, name, last_name)
    VALUES('321', NEW.task, NEW.name, NEW.last_name);
    RETURN NEW;
  ELSE 
    IF NEW.task = '321' AND (
      SELECT cant FROM (
        SELECT name, task, count(*) AS cant
        FROM client_task
        WHERE name = NEW.name AND task = NEW.task
        GROUP BY 1, 2
        HAVING count(*) <=1
      ) t) = 1 THEN
      INSERT INTO client_task(task, name, last_name)
      VALUES('123', NEW.task, NEW.name, NEW.last_name);
      RETURN NEW;
    END IF;
  END IF;
  RETURN NULL;
END; $BODY$ LANGUAGE 'plpgsql';

任何帮助表示赞赏。

【问题讨论】:

  • @DavidVega según este hilo, están preparando el lanzamiento de StackOverflow en español。 Lamentablemente esta página utiliza inglés exclusivamente, por lo tanto dentrán que cerrar tu pregunta。 (我将用户引导到一个据说即将推出的西班牙语 StackOverflow 上的线程,并解释该网站只有英文,所以他的问题将被关闭。)

标签: postgresql


【解决方案1】:

使用pg_trigger_depth()函数,它返回(as stated in the documentation):

PostgreSQL 触发器的当前嵌套级别(如果未调用,则为 0, 直接或间接,从触发器内部)

CREATE TRIGGER insert_task
AFTER INSERT ON employees
FOR EACH ROW
WHEN (pg_trigger_depth() = 0)
EXECUTE PROCEDURE insert_task()

【讨论】:

  • 谢谢@klin 这很有帮助
猜你喜欢
  • 2021-06-05
  • 2011-04-04
  • 2010-10-17
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多