MySQL:相同逻辑下更新触发器正常而插入触发器失效原因问询
故障根因
INSERT触发器失效的核心原因是BEFORE INSERT触发时,待插入的新行还未写入session表,你在子查询中使用where session.session_id = NEW.session_id过滤时,session表中不存在对应记录,子查询返回NULL,最终NEW.session_total被赋值为NULL,看起来就像触发器没有生效。
UPDATE触发器可正常运行,是因为UPDATE操作执行前对应的行已经存在于session表中,WHERE条件可以匹配到有效记录,子查询可以正常返回计算结果。
另外你的原有SQL存在冗余关联:计算逻辑不需要关联session表,直接用NEW携带的字段匹配therapist和rates表即可,去掉冗余关联可以同时解决INSERT触发器失效问题,还能提升触发器执行效率。
修正后代码
INSERT触发器
CREATE TRIGGER triggerCalculateTotalAfterInsertSession BEFORE INSERT ON session FOR EACH ROW BEGIN SET NEW.session_total = ( SELECT IF( NEW.`codeOfService_id` IN (8,10,13,22,23), `rates`.`rates_rate`, NEW.`session_units` * `rates`.`rates_rate` ) AS `total` FROM `therapist` LEFT JOIN `rates` ON( NEW.`codeOfService_id` = `rates`.`codeOfService_id` AND `therapist`.`level_id` = `rates`.`level_id` ) WHERE `therapist`.`therapist_id` = NEW.`therapist_id` LIMIT 1 ); END
优化后的UPDATE触发器(可选,执行效率更高)
CREATE TRIGGER triggerCalculateTotalAfterUpdateSession BEFORE UPDATE ON session FOR EACH ROW BEGIN DECLARE TOTAL decimal(13,2); IF (OLD.session_units <> NEW.session_units OR OLD.therapist_id <> NEW.therapist_id OR OLD.codeOfService_id <> NEW.codeOfService_id) THEN SET NEW.session_total = ( SELECT IF( NEW.`codeOfService_id` IN (8,10,13,22,23), `rates`.`rates_rate`, NEW.`session_units` * `rates`.`rates_rate` ) AS `total` FROM `therapist` LEFT JOIN `rates` ON( NEW.`codeOfService_id` = `rates`.`codeOfService_id` AND `therapist`.`level_id` = `rates`.`level_id` ) WHERE `therapist`.`therapist_id` = NEW.`therapist_id` LIMIT 1 ); END IF; END
内容的提问来源于stack exchange,提问作者Leif Hack
相关产品推荐
相关产品推荐

