如果满足某些条件,我如何自动更新表

时间:2019-08-26 12:17:04

标签: postgresql database-trigger

我想运行触发器,但收到奇怪的错误消息。

我正在使用PostgreSQL。

我要运行此更新:

UPDATE tablename
SET status=5
WHERE id=NEW.id 
AND status=4
AND pk!=NEW.pk;
RETURN NEW;

...每当有人尝试将状态设置为4时。

因此,基本上,我希望每个“ id”仅具有一次状态4。 为了确保这一点,我想将所有其他具有相同ID且status = 4的状态设置为status = 5。

所以我将其放入一个函数中:

CREATE FUNCTION public.statusfunction()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF 
AS $BODY$

BEGIN
UPDATE tablename
SET status=5
WHERE id=NEW.id 
AND status=4
AND pk!=NEW.pk;
RETURN NEW;
END;

$BODY$;
;

并使用触发器执行此函数:

CREATE TRIGGER statustrigger
    BEFORE INSERT OR UPDATE 
    ON public.tablename
    FOR EACH ROW
    EXECUTE PROCEDURE public.statusfunction();

但是当我测试此触发功能时,尝试将状态更新为4,其中具有相同状态和ID的数据集已经存在时,我得到以下错误消息:

ERROR:  stack depth limit exceeded
HINT:  Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.
CONTEXT:  SQL statement "UPDATE public.tablename 
SET status=5
WHERE id=new.id
AND status=4"
PL/pgSQL function statusfunction() line 3 at SQL statement

1 个答案:

答案 0 :(得分:2)

您可以将其包含在触发函数主体中:

IF pg_trigger_depth() > 1 THEN
   RETURN NEW;
END IF;

您的问题是触发器中的UPDATE再次触发了触发器,因此您获得了无穷递归。

检查触发深度是打破无限递归的一种简单方法。