PostgreSQL创建触发器后删除命令失效问题求助
问题原因与解决方案
核心问题:触发器函数返回值错误
在BEFORE DELETE触发器中,返回NEW是完全错误的逻辑:
- DELETE操作不存在
NEW行记录,PostgreSQL会将return new;视为返回NULL,而返回NULL会直接取消当前的DELETE操作,这就是tb_city中id=385的行无法被删除的根本原因。 - 对于BEFORE DELETE触发器,必须返回
OLD才能让PostgreSQL继续执行原有的删除操作。
次要问题:关联表删除语句冗余
你当前的关联表删除语句做了无意义的嵌套查询:
delete from rl_user_city where user_id in (select distinct user_id from rl_user_city where city_id = old.id) and city_id = old.id;
这段代码等价于直接删除city_id = old.id的所有记录,完全不需要嵌套查询筛选user_id,既冗余又影响执行效率。
修正后的代码
1. 重新定义触发器函数
create or replace function delete_user() returns trigger as $$ begin -- 直接删除关联表中对应城市的记录 delete from rl_user_city where city_id = old.id; -- 返回OLD,允许原DELETE操作执行 return old; end; $$ language plpgsql;
2. 重新创建触发器(函数更新后触发器会自动生效,此步骤可选)
drop trigger if exists t_delete_user on tb_city; create trigger t_delete_user before delete on tb_city for each row execute procedure delete_user();
验证执行
修改完成后,再次执行:
delete from tb_city where id = 385;
此时会先删除rl_user_city中所有city_id=385的关联记录,再删除tb_city中id=385的行,符合预期逻辑。
内容的提问来源于stack exchange,提问作者Italo Rodrigo
相关产品推荐
相关产品推荐

