2

If using the Ruby/MSQL library I returned an object of type Mysql::Result, how would I construct a string that loops through the object and constructs a valid MySQL query? I am having trouble figuring out how to drop the final comma from the output below, and how to pass this output back to the query() method.

require 'mysql'
dbh = Mysql.real_connect("host", "user", "pass", "db")
res = dbh.query("SELECT name, category FROM animals")
printf "INSERT INTO animals (name, category) VALUES (\n"
res.each_hash do |row|
printf "('%s', '%s'),\n", row["name"], row["category"]
end
printf ")\n"

#Output    
INSERT INTO animals (name, category) VALUES (
    ('snake', 'reptile'),
    ('frog', 'amphibian'),
    ('tuna', 'fish'),
    ('raccoon', 'mammal'),
    )
0

5 Answers 5

3
values = []
res.each_row do |r|
  values << "(#{r.map{|x| dbh.quote(x) }.join(", ")})"
end
query =<-SQL
  INSERT INTO animals(name, category) VALUES
    (#{values.join(",\n")}
    )
SQL

puts query
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks very much! But how to add the single quotes? query="INSERT INTO animals(name, category) VALUES (#{values.join(",")})" gives INSERT INTO animals(name, category) VALUES ((snake, reptile),(frog, amphibian),(tuna, fish),(racoon, mammal))
use normal string interpolation
2

I'd use join in this case, so rather than looping, and adding a comma each time, do something like:

["One", "Two", "Three"].join(',')

You'll need to turn your hash into an array containing the elements you are interested in first, of course! Try this:

(res.each_hash{|row| "(#{row["name"]}, #{row["category"]})"}).join(",")

Comments

1

in general, if you don't want to just any Ruby magic (like .join() ), you can just loop over the array/hash by index and only add the comma if it is not the last element:

  if(index < array.length) string << ",\n"

3 Comments

join is ruby magic? really? s = ""; def s.foo; puts "foo"; end; s.foo is magic. instance_eval{ define_method...}} is magic. const_missing is magic. join puts things together with another thing, which is kind of underwhelming when you think about it.
meh, call me old school. i agree that it is in the fringe of "ruby magic", but ruby magic none the less (IMHO).
How is join any less 'magic' that length or << for that matter?
1

One way to do this would be to:

    require 'mysql'    
    dbh = Mysql.real_connect("host", "user", "pass", "db")    
    res = dbh.query("SELECT name, category FROM animals")   
    stmt = "INSERT INTO animals (name, category) VALUES ("    
    res.each_hash do |row|
        stmt << "(#{row["name"]}, #{row["category"]})"  
    end    
    stmt << ")"

"how to pass this output back to the query() method"

     dbh.query(stmt)

Comments

0

Thanks for all the suggestions. Using Ben Hughes' example, here is the 'hashed' version:

values = []
res.each_hash do
  |row| values << "('#{row.map{|d,x| dbh.quote(x) }.join("', '")}')" 
  end
puts values.join(",")

query="INSERT INTO animals (name, category) VALUES #{values.join(", ")}"
dbh.query(query)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.