启用触发器时无法删除行
Posted
技术标签:
【中文标题】启用触发器时无法删除行【英文标题】:Cannot delete a row when the trigger is enabled 【发布时间】:2018-04-04 13:47:13 【问题描述】:需要帮助。我在 emp 架构中有一个表和相应的审计表。启用触发器后,我无法从源表中删除该条目。 该表被映射到一个触发器,如下所述。
下面是通用函数,我用它来审核所有表。
Function:
============
CREATE OR REPLACE FUNCTION emp.fn_entry_audit()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
declare
col_name text:='';
audit_table_name text := TG_TABLE_NAME || '_audit';
begin
if TG_OP = 'UPDATE' or TG_OP = 'INSERT' THEN
EXECUTE format('INSERT INTO emp.%1$I SELECT ($1).*,'''||TG_OP||'''',audit_table_name) using NEW;
else
EXECUTE format('INSERT INTO emp.%1$I SELECT ($1).*,'''||TG_OP||'''',audit_table_name) using old;
end if;
return new;
END $function$
Trigger creation
=================
create trigger trig_anish before insert or delete or update on emp.test_empname for each row execute procedure acaas.fn_entry_audit()
Table
======
create table emp.test_empname(id int4,fname varchar(300) not null,lname varchar(400),salary int4,last_modified_dt timestamp);
create table emp.test_empname_audit(id int4,fname varchar(300) not null,lname varchar(400),salary int4,last_modified_dt timestamp,modified_type varchar(10));
两者的区别是modified_type列,会提到数据是insert、update还是delete(TG_OP from above function)。
现在,当我在 emp.test_empname 中插入值时,它会正确插入到 emp.test_empname_audit 中。
select * from emp.test_empname;
emp.test_empname:
==================
id fname lname salary last_modified_dt
===============================================================
1 stacker pentacost 1000 04-04-18
2 lyri pav 2000 04-04-18
3 TEST TEST1 1000 04-04-18
select * from emp.test_empname_audit;
id fname lname salary last_modified_dt modified_type
===============================================================
1 stacker pentacost 1000 04-04-18 INSERT
2 lyri pav 1000 04-04-18 INSERT
2 lyri pav 2000 04-04-18 UPDATE
3 TEST TEST1 1000 04-04-18 Delete
现在,问题是每当我对源表 (test_empname) 执行删除时,查询执行良好,但显示 0 行受影响。 当我在表中查询 select * from test_empname where id=3 时,它仍然存在。但是您可以看到审计中的条目为删除。
我禁用了触发器并执行了删除功能,它执行得很好并且行受到影响。触发器如何影响我的删除功能。请帮忙!!
【问题讨论】:
我的猜测是因为return new
在删除时不是必需的。
但是一个函数应该有返回值,单独删除如何禁用?
@JuanCarlosOropeza :谢谢它的工作,我已经为删除部分返回旧
你可以尝试为删除做一个单独的触发器吗?像这样***.com/questions/38268715/…
很好,但现在您应该测试插入和更新。对于那些你需要返回新的:/
【参考方案1】:
CREATE OR REPLACE FUNCTION acaas.fn_entry_audit1()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
declare
col_name text:='';
audit_table_name text := TG_TABLE_NAME || '_audit';
begin
if TG_OP = 'UPDATE' or TG_OP = 'INSERT' THEN
EXECUTE format('INSERT INTO acaas.%1$I SELECT ($1).*,'''||TG_OP||'''',audit_table_name) using NEW;
return new;
else
EXECUTE format('INSERT INTO acaas.%1$I SELECT ($1).*,'''||TG_OP||'''',audit_table_name) using old;
return old;
end if;
END $function$
【讨论】:
哦,太好了,你可以一次完成。以上是关于启用触发器时无法删除行的主要内容,如果未能解决你的问题,请参考以下文章