postgresql - 如何避免 PostgreSQL 触发器中的递归

标签 postgresql triggers

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

我有 table :

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';

感谢任何帮助。

最佳答案

使用函数pg_trigger_depth()。根据the documentation它返回:

current nesting level of PostgreSQL triggers (0 if not called, directly or indirectly, from inside a trigger)

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

关于postgresql - 如何避免 PostgreSQL 触发器中的递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31765582/

相关文章:

mysql - 触发器内的循环和条件

具有内连接的 MYSQL 触发器

mysql - 如何使用链接的 MySql 服务器更新 SQL 服务器中的行

node.js - 如何在 TypeOrm 中表示 View ?

postgresql - 我需要一个函数来从表中选择 88 个随机行(不重复)

postgresql - 如何设置 Helm Chart 依赖参数

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

wpf - 调试触发器(或者为什么这个触发器不起作用?)

ruby-on-rails - 你可以在 rails 中使用 find_each 进行分组吗?

java - 如何根据给定模式重新排列列表中的项目?