简体   繁体   中英

How to update a row in a MySQL database using Ruby's Sequel toolkit?

This should be the simplest thing but for some reason it's eluding me completely.

I have a Sequel connection to a database named DB . It's using the Mysql2 engine if that's important.

I'm trying to update a single record in a table in the database. The short loop I'm using looks like this:

dataset = DB["SELECT post_id, message FROM xf_post WHERE message LIKE '%#{match}%'"]
dataset.each do |row|
  new_message = process_message(row[:message])
  # HERE IS WHERE I WANT TO UPDATE THE ROW IN THE DATABASE!
end

I've tried:

dataset.where('post_id = ?', row[:post_id]).update(message: new_message)

Which is what the Sequel cheat sheet recommends .

And:

DB["UPDATE xf_post SET message = ? WHERE post_id = ?", new_message, row[:post_id]] 

Which should be raw SQL executed by the Sequel connector. Neither throws an error or outputs any error message (I'm using a logger with the Sequel connection). But both calls fail to update the records in the database. The data is unchanged when I query the database after running the code.

How can I make the update call function properly here?

Your problem is you are using a raw SQL dataset, so the where call isn't going to change the SQL, and update is just going to execute the raw SQL. Here's what you want to do:

dataset = DB[:xf_post].select(:post_id, :message).
            where(Sequel.like(:message, "%#{match}%"))

That will make the where / update combination work.

Note that your original code has a trivial SQL injection vulnerability if match depends on user input, which this new code avoids. You may want to consider using Dataset#escape_like if you want to escape metacharacters inside match , otherwise if match depends on user input, it's possible for users to use very complex matching syntax that the database may execute slowly or not handle properly.

Note that the reason that

DB["UPDATE xf_post SET message = ? WHERE post_id = ?", new_message, row[:post_id]]

doesn't work is because it only creates a dataset, it doesn't execute it. You can actually call update on that dataset to run the query and return number of affected rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM