如何在Rails Rake任务中向MySQL传参及批量修改表编码
Rails Rake任务中的MySQL参数传递与表编码批量修改
问题1:如何在Rails Rake任务中向MySQL查询传递参数?
在Rake任务里给MySQL查询传参数,核心要记住避免SQL注入,同时保证语法合规。这里有两种靠谱的实现方式:
方法1:使用占位符(推荐)
ActiveRecord的数据库连接对象支持用?作为参数占位符,直接把参数以数组形式传给execute方法就行。举个实际例子,比如你要查询指定用户的订单:
task :fetch_user_orders => :environment do target_user_id = 123 # 用?占位,参数放在execute的第二个参数位置 results = ActiveRecord::Base.connection.execute( "SELECT id, amount FROM orders WHERE user_id = ?", target_user_id ) # 遍历处理结果 results.each do |row| puts "订单ID: #{row['id']} | 金额: #{row['amount']}" end end
方法2:用sanitize_sql安全拼接SQL
如果你需要更灵活的SQL拼接逻辑,可以用ActiveRecord的sanitize_sql方法帮你自动转义参数,避免注入风险:
task :filter_products => :environment do target_category = "electronics" min_price = 100 # 用数组形式传入SQL模板和参数,sanitize_sql会自动处理转义 safe_sql = ActiveRecord::Base.sanitize_sql([ "SELECT name, price FROM products WHERE category = ? AND price >= ?", target_category, min_price ]) results = ActiveRecord::Base.connection.execute(safe_sql) end
⚠️ 千万不要直接把变量硬拼进SQL字符串(比如"SELECT * FROM orders WHERE user_id = #{target_user_id}"),这会给SQL注入留后门!
问题2:批量修改数据库表的编码为utf8mb4
你已经搞定了第一步——筛选出非utf8mb4的表,接下来只需要循环这些表执行ALTER语句就行。这里要注意表名转义(防止特殊字符或关键字导致SQL报错),还有一定要先备份数据库!
完整的Rake任务示例:
task :convert_tables_to_utf8mb4 => :environment do # 获取所有编码不符合要求的表 results = ActiveRecord::Base.connection.execute <<-SQL SHOW TABLE STATUS WHERE collation <> 'utf8mb4_unicode_ci' SQL # 循环处理每个表 results.each do |table_info| table_name = table_info["Name"] # 转义表名,适配带特殊字符或关键字的表 escaped_table = ActiveRecord::Base.connection.quote_table_name(table_name) puts "开始修改表: #{table_name}..." # 执行修改字符集的SQL,CONVERT TO会同步修改表和所有列的编码 ActiveRecord::Base.connection.execute <<-SQL ALTER TABLE #{escaped_table} CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci SQL puts "#{table_name} 修改完成!" end puts "所有目标表已完成编码切换!" end
几个关键提醒:
- 先备份数据库:ALTER TABLE是DDL操作,执行前务必备份,防止数据意外丢失。
- 避开业务高峰:修改大表时会锁表,建议在低峰时间段执行。
- 排序规则选择:示例中用了
utf8mb4_unicode_ci,它的排序逻辑更准确;如果追求性能,也可以换成utf8mb4_general_ci。 - 自动同步列编码:
CONVERT TO CHARACTER SET会自动把表的字符集和所有列的字符集一起修改,刚好匹配你的需求。
内容的提问来源于stack exchange,提问作者Ana Isabel
相关产品推荐
相关产品推荐

