在Rails中使用exec_query绑定MySQL参数报错求助
Rails中exec_query绑定MySQL参数的语法错误解决方法
在Rails中使用ActiveRecord::Base.connection.exec_query为MySQL数据库绑定参数时触发SQL语法错误,相关代码及报错信息如下:
错误代码
query = "Select * from accounts where name = ? AND description = ?" ActiveRecord::Base.connection.exec_query(query, name = "SQL", [ [nil, "Some account"], [nil, "Some Desc"] ])
报错信息
SQL (68.7ms) Select * from accounts where name = ? AND description = ?
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? AND description = ?' at line 1
已知两种可行替代方案,但需解决exec_query本身的参数绑定问题,测试环境为mysql2 (0.5.6) + MySQL 8.0:
Account.where("name=? AND description=?", "Some account", "Some Desc")Account.where(name: "Some account", description: "Some Desc")
问题根源与解决方案
问题出在exec_query的第三个参数格式上:MySQL适配器不支持你传入的二维数组格式(这是PostgreSQL适配器的参数写法),导致参数未被正确替换,?直接保留在SQL中引发语法错误。
修正方案1:使用位置占位符?,直接传值数组
query = "SELECT * FROM accounts WHERE name = ? AND description = ?" ActiveRecord::Base.connection.exec_query(query, "SQL", ["Some account", "Some Desc"])
修正方案2:使用命名占位符,传哈希数组
如果需要更清晰的参数映射,可以用命名占位符:
query = "SELECT * FROM accounts WHERE name = :name AND description = :description" ActiveRecord::Base.connection.exec_query(query, "SQL", [ { name: "name", value: "Some account" }, { name: "description", value: "Some Desc" } ])
说明
exec_query的第三个参数binds在不同数据库适配器中有差异:
- MySQL适配器:使用
?时直接传值数组;使用命名占位符时传包含name和value的哈希数组。 - PostgreSQL适配器:需要传二维数组,格式为
[类型, 值],其中类型可以为nil由适配器推断。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

