Ruby DBI select_all vs execute-fetch/each-finish

与世无争的帅哥 提交于 2019-12-10 21:49:19

问题


Here is my sample code for using DBI:

dbh = DBI.connect("DBI:Mysql:host=#{server};database=mysql", user, pass)
rows = dbh.select_all("SHOW TABLES")

Here the rows is printed as below:

[["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"],
 ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"],
 ["user"]]

This is printing the last table in mysql database, but the total number of records is proper.

If I do this using execute-fetch/each-finish sequence, something like below:

sth = dbh.execute("SHOW TABLES")
sth.each do |row|
  rows << row[0]
end
sth.finish

But it gives me proper results like:

["columns_priv", "db", "func", "help_category", "help_keyword", "help_relation",
 "help_topic", "host", "proc", "procs_priv", "tables_priv", "time_zone", "time_z
one_leap_second", "time_zone_name", "time_zone_transition", "time_zone_transitio
n_type", "user"]

Help me out with the issue?


回答1:


The same is also happenning when I query an MS SQL DB using DBI.connect("DBI:ODBC:Driver={SQL Server};...")

My work around was to forcably convert the DBI::Row to an array:

sth = dbh.execute "..."
begin
  return sth.map{ |row| row.to_a }
ensure
  sth.finish
end

I'll bet $1,000 that the issue is to do with buffer reuse - a possible 'performance' enhancement that has had underirable side effects!




回答2:


I guess that dbh.select_all returns an instance of Enumerator, which yields the same row on each iteration. See this pseudocode to understand what I mean:

def select_all(query)
  db_row = Row.new
  reader = @connection.execute_reader(query)
  Enumerator.new do |yielder|
    until reader.end?
      db_row.populate_from(reader)
      yielder.yield db_row
      reader.next!
    end
  end
end

Thus, if you're using select_all without block, an Enumerator will be returned, which basically yields the same db_row object.

This is just a guess, but, I believe the truth is nearby.

UPD: Source code here https://github.com/erikh/ruby-dbi/blob/master/lib/dbi/handles/statement.rb (see fetch method definition) says that I was wrong, because @row is duplicated on each iteration. Well, probably error is somewhere up the stack...



来源:https://stackoverflow.com/questions/8972379/ruby-dbi-select-all-vs-execute-fetch-each-finish

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!