如何使用 Ruby DBI 的“select_all”与“执行获取/每次完成”相比
这是我使用 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"]
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")
The rows printed look like:
[["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"],
["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"], ["user"],
["user"]]
This is printing the last table in a MySQL database, but the total number of records is proper.
If I do this using execute-fetch/each-finish sequence, something like:
sth = dbh.execute("SHOW TABLES")
sth.each do |row|
rows << row[0]
end
sth.finish
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"]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当我使用 DBI.connect("DBI:ODBC:Driver={SQL Server};...") 查询 MS SQL DB 时,也会发生同样的情况。
我的解决方法是强制转换 DBI ::行到数组:
我敢打赌 1,000 美元,这个问题与缓冲区重用有关 - 可能的“性能”增强,但产生了令人不快的副作用!
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:
I'll bet $1,000 that the issue is to do with buffer reuse - a possible 'performance' enhancement that has had underirable side effects!
我猜想 dbh.select_all 返回一个 Enumerator 实例,它在每次迭代中生成相同的行。请参阅此伪代码以了解我的意思:
因此,如果您使用不带块的 select_all ,则会返回一个枚举器,这基本上会产生相同的 db_row 对象。
这只是一个猜测,但是,我相信真相就在附近。
源代码
fetch
方法定义表明我错了,因为@row
在每次迭代中都是dup
复制的。好吧,错误可能出在堆栈的某个地方。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: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
isdup
licated on each iteration. Well, probably the error is somewhere up the stack.