MySQL预处理语句使用小数取整值作参数触发EXECUTE报错
问题分析与解决
错误原因
你遇到的ERROR 1210 (HY000)是因为预处理语句中LIMIT的参数要求是整数类型变量,而你的@a变量虽然数值是整数,但类型却是DECIMAL(或浮点型)——这是因为(COUNT(*)-1)/2是除法操作,返回的是DECIMAL类型,即使经过FLOOR取整,结果类型依然是DECIMAL,不符合LIMIT对参数类型的要求。
验证依据
你提到的两个观察正好能印证这点:
FLOOR(COUNT(*)-1):COUNT(*)-1是整数类型(BIGINT),FLOOR作用后依然是整数类型,所以能正常运行;SELECT FLOOR((COUNT(*)-1)/2):单独查询时MySQL会自动处理类型显示,但变量赋值时会保留DECIMAL类型,导致后续EXECUTE报错。
解决方法
有两种简单的修正方式:
方式1:强制转换变量为整数类型
把@a的赋值语句改成强制转换为整数类型,比如用CAST或CONVERT:
SELECT @a:=CAST(FLOOR((COUNT(*)-1)/2) AS UNSIGNED) FROM <Table>; PREPARE STMT FROM 'SELECT * FROM <Table> LIMIT ?, 1'; EXECUTE STMT USING @a;
方式2:使用整数除法替代浮点除法
用MySQL的整数除法操作符DIV,直接得到整数结果,无需FLOOR,变量类型自然是整数:
SELECT @a:=(COUNT(*)-1) DIV 2 FROM <Table>; PREPARE STMT FROM 'SELECT * FROM <Table> LIMIT ?, 1'; EXECUTE STMT USING @a;
另外,你第一条语句里的ORDER BY <Column>是多余的——因为COUNT(*)是聚合函数,不带GROUP BY时整个表只会返回一行结果,排序操作不会改变最终的@a值,建议去掉以节省性能。
内容的提问来源于stack exchange,提问作者Kaushik Acharya
相关产品推荐
相关产品推荐

