How to use Ruby DBI's 'select_all' vs 'execute-fetch/each-finish'

后端 未结 2 1742
余生分开走
余生分开走 2020-12-21 07:53

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\")


        
相关标签:
2条回答
  • 2020-12-21 08:36

    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.


    The source code fetch method definition says that I was wrong, because @row is duplicated on each iteration. Well, probably the error is somewhere up the stack.

    0 讨论(0)
  • 2020-12-21 08:46

    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!

    0 讨论(0)
提交回复
热议问题