MySQL存储过程INT参数校验失效,小数输入被截断问题求助
问题原因分析
当你把存储过程的参数类型指定为INT时,MySQL在调用存储过程前就会自动对传入的参数做隐式类型转换——任何小数都会被直接截断成整数部分(比如3.24会被转成3)。等参数进入存储过程内部时,customer_id已经是整数了,你写的customer_id != TRUNCATE(customer_id,0)判断自然永远不会触发,小数校验也就失效了。
可行的参数校验方案
方案1:修改参数类型,在存储过程内完成完整校验
把参数类型改成DECIMAL(10,2)(或其他精度的DECIMAL类型,避免浮点数精度问题),这样传入的小数会被完整保留,再判断是否为整数。修改后的存储过程代码如下:
DELIMITER // CREATE PROCEDURE GetCustomerReceipts(IN customer_id DECIMAL(10,2)) BEGIN IF customer_id != FLOOR(customer_id) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid id code1: 客户ID必须为整数'; ELSEIF customer_id < 0 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid id code2: 客户ID不能为负数'; ELSE SELECT * FROM receipts r WHERE r.customer_id = customer_id; END IF; END // DELIMITER ;
- 用
FLOOR()或TRUNCATE()判断是否为整数都可以,效果一致 - 推荐用
45000作为自定义错误的SQLSTATE,这是MySQL官方推荐的通用用户自定义错误码
方案2:在调用端(应用层)提前校验
如果必须保留INT类型的参数,那就在调用存储过程的应用代码里先做校验:只允许传入纯整数格式的参数,非整数直接拒绝调用,从源头避免无效参数进入存储过程。比如在Python/Java等业务代码里,先判断输入是否为整数,再执行存储过程调用。
内容的提问来源于stack exchange,提问作者rax0000
相关产品推荐
相关产品推荐

