postgresql - 更新后使用触发器更新表

标签 postgresql triggers sql-update plpgsql postgresql-9.1

我有两张 table

 batch (batch_id,start_date,end_date,batch_strength,is_locked)
 sem (user_id,is_active,no_of_days)

我已经执行了下面给出的触发过程,然后使用查询更新表

CREATE OR REPLACE FUNCTION em_batch_update()
  RETURNS trigger AS $em_sem_batch$
BEGIN

UPDATE batch set is_locked='TRUE'
where (start_date
       + (select no_of_days from sem
          WHERE is_active='TRUE' and user_id='OSEM')
      ) <= current_date;

return NEW;

END;
$em_sem_batch$  LANGUAGE plpgsql;

CREATE TRIGGER em_sem_batch
BEFORE UPDATE ON batch FOR EACH ROW EXECUTE PROCEDURE em_batch_update();

update em_batch set batch_strength=20 where batch_id='OD001C001B3';

发生错误:

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.

最佳答案

有几种方法可以防止您在触发器中内置的无限递归,最优雅和高效的可能是添加一个 WHERE UPDATE 的条款触发器函数中的语句:

CREATE OR REPLACE FUNCTION em_batch_update()
  RETURNS trigger AS
$func$
BEGIN

UPDATE batch b
SET    is_locked = TRUE
FROM   sem s
WHERE  s.is_active
AND    s.user_id = 'OSEM'
AND    b.start_date <= (current_date - s.no_of_days)
AND    b.is_locked IS DISTINCT FROM TRUE; -- prevent infinite recursion!

RETURN NULL;

END
$func$  LANGUAGE plpgsql;

CREATE TRIGGER em_sem_batch
BEFORE UPDATE ON batch
FOR EACH STATEMENT
EXECUTE PROCEDURE em_batch_update();

我改变了一些其他的东西来走向理智:

Trigger functions invoked by per-statement triggers should always return NULL.

  • batch.is_lockedsem.is_active看起来像 bool 列。使用适当的 boolean data type为他们。我的代码以此为基础。

  • 我还重写了你的 UPDATE查询完全。特别是 batch.start_date 上的条件以便在可用时使用索引。

  • 如果 batch.is_locked定义 NOT NULL , WHERE条件可以简化为:

        AND    b.is_locked = FALSE;
    

关于postgresql - 更新后使用触发器更新表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14137932/

相关文章:

python - 在 Django 1.10 中将三元组与排名搜索相结合

sql - 有条件地删除数组字段 PostgreSQL 中的项目

postgresql - 允许一些角色更新列,如果它是 NULL,则允许其他一些角色

PLSQL:如何防止触发器中的错误取消原始操作?

sql - 为空 vs. 等于空

sql-server - 如何使用 SQL Server 中另一列的数据更新一列?

postgresql - 将输出(数据库密码)从 Terraform 传递到 CICD 管道中的 Kubernetes list

postgresql - 转储 RDS Postgres 查询的内容

oracle - PLS-00382 : expression is of wrong type Trigger

"WHERE"附近的 Android 数据库更新 : syntax error