关于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, IN `_Price` decimal _res : 执行结果,0表示失败,成功时返回订单的id */ INSERT INTO t_order (`orderNo`,`price`) VALUES (_OrderNo,_Price); select @@Identity INTO _res; END;
这个坑,记录在这里,也是对自己的一个提醒吧!
感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
欢迎各位转载,但必须在文章页面中给出作者和原文链接!