红宝石mysql2在单个查询多个语句(Ruby mysql2 multiple statements

2019-09-18 13:06发布

我有一个问题,我更新数百万行的在我的数据库,因此而不是更新每一个单独我想加入的团体〜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)

有没有人碰到这之前? 或者有什么建议的另一种方法?

Answer 1:

简短的回答这个问题是当MULTI_STATEMENTS启用的MySQL希望你来处理您的查询的结果。

速战速决是每个组的多个更新语句之后,做一些类似的

  while db_write.next_result
    db_write.store_result rescue ''
  end


Answer 2:

你为什么不只是::

无需多次运行它....

UPDATE pew SET x = 10 WHERE x IS NULL


Answer 3:

据我所知,这是一个结果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


Answer 4:

接下来的SQL语句之前写了下面的命令。

ActiveRecord::Base.connection.raw_connection.abandon_results!

它将使一个新的SQL命令执行。



文章来源: Ruby mysql2 multiple statements in single query