我有一个问题,我更新数百万行的在我的数据库,因此而不是更新每一个单独我想加入的团体〜1000条语句到一个查询。
我已经启用MULTI_STATEMENTS像这样
client = Mysql2::Client.new(:host => 'localhost', :database => 'mehdb', :username => "root", :password => "", :flags => Mysql2::Client::MULTI_STATEMENTS)
以下是我正在运行的代码示例
sql = "SELECT id, x FROM pew WHERE x IS NULL LIMIT 1000"
results = db_read.query(sql)
while results.count > 0
updates = ''
results.each do |r|
updates += "UPDATE pew SET x = 10 WHERE id = #{r['id']};"
end
db_write.query(updates) unless updates.empty?
results = db_read.query(sql)
end
这项工作是正常的,通过第一次运行时,但是当它关闭触发第二组更新我收到此错误信息
`query': Commands out of sync; you can't run this command now (Mysql2::Error)
有没有人碰到这之前? 或者有什么建议的另一种方法?
简短的回答这个问题是当MULTI_STATEMENTS启用的MySQL希望你来处理您的查询的结果。
速战速决是每个组的多个更新语句之后,做一些类似的
while db_write.next_result
db_write.store_result rescue ''
end
你为什么不只是::
无需多次运行它....
UPDATE pew SET x = 10 WHERE x IS NULL
据我所知,这是一个结果Mysql的内部保护 - 您在查询数据库和流的结果,如果在你还将更新的结果,你不能保证一致性的任何级别的中间。
如果你知道你是安全做出改变作为流程的一部分,你可以解决,通过简单地创建第二个连接:
reading_client = Mysql2::Client.new(:host => 'localhost', :database => 'mehdb', :username => "root", :password => "", :flags => Mysql2::Client::MULTI_STATEMENTS)
updating_client = Mysql2::Client.new(:host => 'localhost', :database => 'mehdb', :username => "root", :password => "", :flags => Mysql2::Client::MULTI_STATEMENTS)
sql = "SELECT id, x FROM pew WHERE x IS NULL LIMIT 1000"
results = reading_client.query(sql)
while results.count > 0
updates = ''
results.each do |r|
updates += "UPDATE pew SET x = 10 WHERE id = #{r['id']};"
end
updating_client.query(updates) unless updates.empty?
results = reading_client.query(sql)
end
接下来的SQL语句之前写了下面的命令。
ActiveRecord::Base.connection.raw_connection.abandon_results!
它将使一个新的SQL命令执行。