如何使用 Ruby 的 Sequel 工具包更新 MySQL 数据库中的一行?

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

这应该是最简单的事情,但出于某种原因,我完全无法理解。

我有一个 Sequel 连接到名为 DB 的数据库。如果这很重要,它正在使用 Mysql2 引擎。

我正在尝试更新数据库中 table 中的单个记录。我使用的短循环如下所示:

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

我试过:

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

这就是the Sequel cheat sheet recommends

并且:

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

这应该是原始的 SQL 由 Sequel 连接器执行。既不会抛出错误也不会输出任何错误消息(我正在使用带有 Sequel 连接的记录器)。但是这两个调用都无法更新数据库中的记录。 运行代码后查询数据库,数据没有变化

我怎样才能在这里正确调用更新函数?

您的问题是您使用的是原始 SQL 数据集,因此 where 调用不会更改 SQL,而 update 只是执行原始 SQL。这是你想要做的:

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

这将使 where/update 组合起作用。

请注意,如果 match 依赖于用户输入,则您的原始代码有一个微不足道的 SQL 注入漏洞,此新代码避免了这一漏洞。如果您想转义 match 中的元字符,您可能需要考虑使用 Dataset#escape_like,否则如果 match 取决于用户输入,用户可能会使用数据库可能会使用的非常复杂的匹配语法执行缓慢或处理不当

请注意

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

不起作用是因为它只创建了一个数据集,并没有执行它。您实际上可以对该数据集调用 update 以 运行 查询和 return 受影响的行数。