考虑这个程序
require 'dbi'
handle = DBI.connect('DBI:Mysql:tasks', 'root', 'stupid')
handle.select_all('select * from tasks') do |row|
puts row.inspect
end
rows = handle.select_all('select * from tasks')
puts rows.inspect
第一次调用select_all
传递一个块,它用来遍历表行,就像它想象的那样。这是迭代的标准Ruby习语,所以它当然有效。
第二个调用应该返回相同的数据,但是一次性打包,打包在一个数组中。数组实际包含的是表格的最后一行一遍又一遍!
这是一个错误,还是我做错了什么?
答案 0 :(得分:1)
我也偶然发现了这一点。经过大量研究后,我决定与特定语句手相关的每个DBI::Row
实例引用相同的内存。更糟糕的仍然是复制或克隆它没有任何区别。获得正确副本的唯一方法是将其转换为.to_a
的数组,这意味着您将失去方法:(
我煞费苦心地提交了一份关于rubyforge的错误报告 - 不是因为我认为它会得到修复,而是因为它可能会帮助其他一些扯掉头发的傻瓜。
答案 1 :(得分:0)
我也偶然发现了这一点。经过大量研究后,我决定与特定语句关联的每个DBI :: Row实例都引用相同的内存。更糟糕的仍然是复制或克隆它没有任何区别。获得正确副本的唯一方法是将其转换为带有.to_a的数组,这意味着您放弃了方法:(
我煞费苦心地提交了一份关于rubyforge的错误报告 - 不是因为我认为它会得到修复,而是因为它可能会帮助其他一些扯掉头发的傻瓜。
事实上,我刚刚将几个脚本转换为DBI的Sequel。续集看起来非常好,因为它允许ORM类型访问以及支持像dbi这样的原始sql。
翻译很直接。