为什么SQLite中编写的触发器无法阻止向users_items表插入行?
触发器无法阻止插入的核心原因
- 未处理无有效信用时的NULL值
当用户没有任何未过期的信用记录时,SELECT sum(number_of_items) FROM credits WHERE user_id = NEW.user_id AND expiration >= datetime('now')会返回NULL。SQL规则中所有数值和NULL的比较结果都为NULL,无法触发CASE的WHEN分支,RAISE终止语句永远不会执行,触发器直接放行插入操作。 - 边界判断逻辑适配问题(可选优化)
当前的>=判断符合「允许最多等于信用额度的条目数」的业务逻辑,但如果没有处理NULL的问题,该判断在用户无有效信用时完全失效。
修正方案
使用COALESCE函数将求和返回的NULL结果转为0即可,修正后触发器代码如下:
CREATE TRIGGER check_has_enough_credits_to_monitor_item BEFORE INSERT ON users_items BEGIN SELECT CASE WHEN (SELECT COUNT(*) FROM users_items WHERE user_id = NEW.user_id) >= COALESCE((SELECT sum(number_of_items) FROM credits WHERE user_id = NEW.user_id AND expiration >= datetime('now')), 0) THEN RAISE (ABORT, 'No more items allowed') END; END;
修改后效果:
- 用户无有效信用时,求和结果转为0,哪怕是第一次插入(已有条目数为0)也会触发报错,阻止插入
- 用户有有效信用时,已有条目数达到额度上限就会阻止新插入,符合预期需求
内容的提问来源于stack exchange,提问作者knowledge_seeker
相关产品推荐
相关产品推荐

