亚星娱乐登录老虎机 如何Mysql触发器中抛出一个异常
扫描二维码
随时随地手机看文章
当想Mysql出发其中插入或者更新一条数据的时候,我希望使用触发器进行一些检查工作。虽然这些工作可以使用PHP来完成,但考虑到公司做PHP的小伙子是个新手,为了简化PHP端的业务,使用触发器来实现可靠性应该更强, 在平时的应用中我们经常使用触发器来做一些关联表的字段值的更新操作。这次,我想做的事,在插入数据之前进行一次检查。
当前的应用场景是,当创建订单的时候,先检查用户账户的余额,余额不足则终止订单创建操作。通过查阅资料,从Mysql 5.5 开始为我们提供了SIGNAL函数来实现这个功能。
CREATE TRIGGER `tg_order_create` AFTER INSERT ON `tp_order` FOR EACH ROW BEGIN DECLARE msg varchar(200); IF 2=NEW.condition THEN UPDATE `tp_user` SET `frozen_amount`=`frozen_amount`+NEW.amount WHERE `id`=NEW.uid AND `amount`-`frozen_amount` > NEW.amount; IF ROW_COUNT() <> 1 THEN set msg = "用户余额不足以完成支付."; SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg; END IF; ELSEIF 3=NEW.condition THEN UPDATE `tp_user` SET `amount`=`amount`-NEW.amount WHERE `id`=NEW.uid AND `amount`-`frozen_amount` > NEW.amount; IF ROW_COUNT() <> 1 THEN set msg = "用户余额不足以完成支付."; SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg; END IF; END IF; END;
这里这条触发器的功能是库存操作,当库存足够的时候 减少库存,否则 抛出一个异常并报告商品库存不足:
CREATE TRIGGER `TG_order_detail_dec_stock` BEFORE INSERT ON `tp_order_detail` FOR EACH ROW BEGIN DECLARE msg VARCHAR(200); UPDATE `tp_stock` SET `num`=`num`-NEW.num WHERE `goods_id`=NEW.goods_id AND `mid`=NEW.mid AND `num`>=NEW.num; IF ROW_COUNT() <> 1 THEN SELECT CONCAT(`name`, ' 库存不足.') INTO msg FROM `tp_goods` WHERE `id`=NEW.goods_id; SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg; END IF; END;
在PHP端的处理(注:使用ThinkPHP框架):
//前面省略若干行.... try { if (false === ($order_pk = $tbl_order->add($order))) { $tbl->rollback(); echo json_encode(array('success' => -1, 'message' => "创建订单失败!."), JSON_UNESCAPED_UNICODE); return; } }catch (PDOException $e){ $errInfo=$e->errorInfo[2]; $tbl->rollback(); echo json_encode(array('success' => -1, 'message' => "创建订单失败!,{$errInfo}"), JSON_UNESCAPED_UNICODE); return; } //后面省略若干行....
参考资料:
Mysql5.5 SINGAL 语法(英文)