use*_*539 2 postgresql triggers plpgsql sql-update postgresql-9.1
我有两张桌子
batch (batch_id,start_date,end_date,batch_strength,is_locked)
sem (user_id,is_active,no_of_days)
Run Code Online (Sandbox Code Playgroud)
我已经执行了下面给出的触发器过程,然后使用查询更新表
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';
Run Code Online (Sandbox Code Playgroud)
发生了错误:
错误:超出堆栈深度限制
提示:确保平台的堆栈深度限制足够后,增加配置参数"max_stack_depth"(当前为2048kB).
有几种方法可以防止内置到触发器中的无限递归,最优雅和高性能的可能是在触发器函数中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();
Run Code Online (Sandbox Code Playgroud)
我改变了一些其他的东西来走向理智:
每个语句触发器调用的触发器函数应始终返回NULL.
batch.is_locked
和sem.is_active
看起来像布尔列.为它们使用适当的boolean
数据类型.我的代码正在构建它.
我也UPDATE
完全重写了你的查询.特别是条件,batch.start_date
以便可以使用索引.
如果batch.is_locked
已定义NOT NULL
,则WHERE
条件可简化为:
AND b.is_locked = FALSE;
Run Code Online (Sandbox Code Playgroud)您的UPDATE
触发器UPDATE
在同一表上运行另一个触发器,它将再次触发该触发器,因此您将获得无限递归。您可能需要重新设计一下,但是如果不解释您要尝试做的事情,很难说怎么做。
归档时间: |
|
查看次数: |
5688 次 |
最近记录: |