将mysql预处理语句作为哈希数组获取

时间:2013-06-13 09:16:00

标签: mysql ruby arrays hash prepared-statement

我正在努力使用ruby的mysql gem并准备陈述 我希望最终得到与each_hash对结果相同的结果,但是在prepare语句中也不支持它。 所以我带来了这个可怕的混乱。

  stmt = @db.prepare("SELECT mat_id, name, qty FROM materials WHERE mat_id = ? ")

  #those 3 lines hurt my eyes
  res = stmt.execute(params[:id])
  mat_id, name, qty  =  res.bind_result(Integer, String, Integer).fetch
  @material = [mat_id: mat_id, name: name, qty: qty]

必须有一种更好的方法来获取结果并获得一系列哈希值。

更好的mysql gem可能是一个有效的答案。 ORM不是。

3 个答案:

答案 0 :(得分:2)

看到评论,我仍然会发布续集链接作为答案:

http://sequel.rubyforge.org/

你根本不需要使用Sequel的模型部分。事实上,文档有一整节专门讨论SQL迷们:

http://sequel.rubyforge.org/rdoc/files/doc/sql_rdoc.html

示例查询:

DB.fetch("SELECT * FROM albums WHERE name LIKE ?", 'A%') do |row|
  puts row[:name]
end

答案 1 :(得分:2)

Oneliner!

Hash[stmt.result_metadata.fetch_fields.map(&:name).zip( stmt.fetch )]

或更强大

row = stmt.fetch
Hash[stmt.result_metadata.fetch_fields.map(&:name).zip( row )] if row

答案 2 :(得分:1)

根据http://tmtm.org/en/mysql/ruby/,结果有一个“each_hash”方法,但语句没有。屁股真是太痛苦了......

#A proxy for the statement class
class Stmt

  def each_hash
    fields = @target.result_metadata.fetch_fields.map do |f| f.name.to_sym end 
    @target.execute.each do |x| 
      hash = {}
      fields.zip(x).each do |pair|
        hash[pair[0]] = pair[1]
      end 
      yield hash
    end 
  end 

  def initialize(target)
    @target = target
  end 

  def method_missing(name, *args, &block)
    @target.send(name, *args, &block)
  end 
end

现在,你可以这样做:

Stmt.new(@db.prepare(...).execute(...)).each_hash do |x|
  puts x
end

并且您可以将每行循环作为哈希值。

我还没有为多次执行测试过这个

相关问题