Ruby DBI select_all vs execute-fetch / each-finish
这是我使用DBI的示例代码:
dbh = DBI.connect("DBI:Mysql:host=#{server};database=mysql", user, pass) rows = dbh.select_all("SHOW TABLES")
这里的行打印如下:
[["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"]]
这是在mysql数据库中打印最后一个表,但记录总数是正确的。
如果我使用execute-fetch / each-finish序列执行此操作,如下所示:
sth = dbh.execute("SHOW TABLES") sth.each do |row| rows << row[0] end sth.finish
但它给了我正确的结果,如:
["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"]
帮我解决这个问题?
当我使用DBI.connect("DBI:ODBC:Driver={SQL Server};...")
查询MS SQL DB时,也会发生同样的情况DBI.connect("DBI:ODBC:Driver={SQL Server};...")
我的工作是强行将DBI :: Row转换为数组:
sth = dbh.execute "..." begin return sth.map{ |row| row.to_a } ensure sth.finish end
我敢打赌1000美元,这个问题与缓冲区重用有关 – 一种可能的“性能”增强,它具有不可抗拒的副作用!
我猜dbh.select_all
返回一个Enumerator实例,它在每次迭代时产生相同的行。 看到这个伪代码来理解我的意思:
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
因此,如果您使用select_all而不使用块,则将返回一个枚举器,它基本上产生相同的db_row对象。
这只是猜测,但我相信事实就在附近。
UPD:这里的源代码https://github.com/erikh/ruby-dbi/blob/master/lib/dbi/handles/statement.rb (请参阅获取方法定义)说我错了,因为@row
是重复的在每次迭代。 好吧,可能错误是堆栈的某个地方……