关于mysql存储过程中传decimal值会⾃动四舍五⼊的这个坑容我说⼏句题外话:我的⼯作⽇常是⽤微软系的,SQL SERVICE 很强⼤,我也很习惯很喜欢⽤存储过程。和MySQL结缘,是在五年前,因为⼀些原因,公司要求⽤开源免费的数据库。很多时候,⽤mysql的程序员是不会去⽤存储过程的,除了调试⿇烦外,还有其它各种⼩问题。说实在的,MySQL这些年发展很快,但和SQL SERVICE的差距还是很⼤的。好了,不说废话了,⾔归正转。
⾸先,描述我的场景
假如,我们有⼀张订单表 t_order 结构如下:
字段名类型描述id int(11) <auto_increment>id,⾃增,主键orderNo varchar(20)订单编号,唯⼀约束
price decimal(10,2)价格
我们不要去纠结这张表的完整性,也不要去纠结为什么价格不直接⽤int表⽰单位为分的额。现在假如,我们写⼀个⽣成订单存储过程:CREATE PROCEDURE `p_order_create`(IN `_OrderNo` tinytext,IN `_Price` decimal,OUT `_res` int)
BEGIN
/*
⽤途:⽣成订单
参数:
IN `_OrderNo` tinytext,
IN `_Price` decimal
_res : 执⾏结果,0表⽰失败,成功时返回订单的id
*/
INSERT INTO t_order
(`orderNo`,`price`)
VALUES
(_OrderNo,_Price);
select@@Identity INTO _res;
END;
当我们在调⽤时,给价格传⼊的是⼀个⼩数时,如:
CALL p_order_create('abc',5.8,@res)
我们会发现,存⼊表 t_order中的这⼀条数据,price是6,四舍五⼊了。。。。,说实在的,之前我⼀直都是⽤int来表⽰钱的最⼩单位(当前业务的最⼩单位),⽐如RMB⼀元,我就存100的整型,所以⼀直没有留意到MySQL这个坑。当然了,这个坑的解决⽅案也很简单,我们只要给decimal在申明时指定它的精度,⽐如decimal(10,2),即存储过程可以改为:
CREATE PROCEDURE `p_order_create`(IN `_OrderNo` tinytext,IN `_Price` decimal(10,2),OUT `_res` int)
BEGIN
/*
⽤途:⽣成订单
参数:
IN `_OrderNo` tinytext,mysql视图和存储过程
IN `_Price` decimal
_res : 执⾏结果,0表⽰失败,成功时返回订单的id
*/
INSERT INTO t_order
(`orderNo`,`price`)
VALUES
(_OrderNo,_Price);
select@@Identity INTO _res;
END;
这个坑,记录在这⾥,也是对⾃⼰的⼀个提醒吧!