MySQL将COUNT统计结果存入变量时触发1064语法错误
错误根因
你的动态SQL拼接逻辑写错了:currentTableRows是你用来存统计结果的变量,你在拼接SELECT ... INTO语句的时候,直接把这个变量当前持有的值拼到了SQL字符串里,而不是把它作为接收结果的变量写入SQL语法。
从报错信息可以看到,你执行时currentTableRows的初始值是0,最终拼出来的非法SQL长这样:
SELECT COUNT(id) INTO 0 FROM z_wallet_txn_2021_02
INTO子句后面必须跟合法的变量名,不能直接跟数字字面量,所以触发1064语法错误。
修复方法
根据你用的变量类型选对应写法即可:
- 如果用
@开头的用户变量存结果,不需要把变量拼进字符串,直接把变量名写在动态SQL文本里就行:
-- 注意INTO后面直接写接收结果的用户变量,不要做拼接 SET @findTableRows = CONCAT('SELECT COUNT(id) INTO @currentTableRows FROM `', aTableName, '`'); PREPARE stmt2 FROM @findTableRows; EXECUTE stmt2; DEALLOCATE PREPARE stmt2; -- 执行完释放预处理句柄,避免内存泄漏 -- 后续直接读@currentTableRows就能拿到COUNT结果 SELECT @currentTableRows;
- 如果你是在存储过程里用
DECLARE定义的无@前缀的局部变量存结果,因为预处理语句无法直接访问存储过程局部变量,需要用用户变量做中转:
-- 假设你已经提前定义:DECLARE currentTableRows INT DEFAULT 0; SET @findTableRows = CONCAT('SELECT COUNT(id) INTO @tempCount FROM `', aTableName, '`'); PREPARE stmt2 FROM @findTableRows; EXECUTE stmt2; DEALLOCATE PREPARE stmt2; -- 把中转用户变量的值赋值给局部变量 SET currentTableRows = @tempCount;
注意事项
- 动态SQL里只有表名、列名这类可变标识符需要通过CONCAT拼接,固定的语法关键字、固定的接收结果变量直接写在SQL字符串里即可,不要额外拼接。
- 拼接表名、列名的时候建议两侧加上反引号包裹,避免表名和SQL关键字重名、带特殊字符时触发语法错误。
- 预处理语句执行完必须显式释放,否则长时间运行存储过程会造成不必要的内存占用。
内容的提问来源于stack exchange,提问作者Sagar Sangwan
相关产品推荐
相关产品推荐

