这应该是最简单的事情,但出于某种原因,我完全无法理解。
我有一个 Sequel 连接到名为 DB
的数据库。如果这很重要,它会使用 Mysql2 引擎。
我正在尝试更新数据库表中的单个记录。我使用的短循环如下所示:
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]]
这应该是 Sequel 连接器执行的原始 SQL。既不会抛出错误也不会输出任何错误消息(我正在使用带有 Sequel 连接的记录器)。但是这两个调用都无法更新数据库中的记录。运行代码后查询数据库,数据没有变化。
如何在这里使更新调用正常运行?
最佳答案
您的问题是您使用的是原始 SQL 数据集,因此 where
调用不会更改 SQL,而 update
只会执行原始 SQL SQL。这是您想要执行的操作:
dataset = DB[:xf_post].select(:post_id, :message).
where(Sequel.like(:message, "%#{match}%"))
这将使 where
/update
组合起作用。
请注意,如果 match
取决于用户输入,则您的原始代码有一个微不足道的 SQL 注入(inject)漏洞,而这个新代码避免了这种情况。如果您想转义 match
中的元字符,您可能需要考虑使用 Dataset#escape_like
,否则如果 match
取决于用户输入,则可能用户使用非常复杂的匹配语法,数据库可能执行缓慢或无法正确处理。
注意原因
DB["UPDATE xf_post SET message = ? WHERE post_id = ?", new_message, row[:post_id]]
不起作用是因为它只创建了一个数据集,并没有执行它。您实际上可以对该数据集调用 update
来运行查询并返回受影响的行数。
关于mysql - 如何使用 Ruby 的 Sequel 工具包更新 MySQL 数据库中的一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33095163/