如何使用Sequel运行原始的SQL查询

21

我还不清楚使用Sequel运行原始SQL查询的正确方法。

目前我正在尝试这样做:

DB.fetch("SELECT * FROM zone WHERE dialcode = '#{@dialcode}' LIMIT 1") do |row|
 @zonename = row
end

我该如何以原始SQL运行查询,然后像正常情况下一样访问结果?

if @zonename.name = "UK"
2个回答

22
请注意,代替使用以下代码:
DB.fetch("SELECT * FROM zone WHERE dialcode = '#{@dialcode}' LIMIT 1")

你应该这样做:

DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode)

如果您不控制@dialcode的内容,否则将会存在 SQL 注入的风险。


你能告诉我fetch在底层调用了哪个方法来转义用户输入吗?我有一个复杂的查询,由许多方法构建而成,并且需要在构建查询时单独转义用户输入,而不是在数据库调用中。 - Mike H-R
抱歉,我在查找时在文档中找到了它(我正在阅读文档),现在将其发布在此供其他人使用:https://github.com/jeremyevans/sequel/blob/cf1e987c1c2f7e74dca5c0f8312149bede659a21/doc/security.rdoc。该方法是 DB.literal(my_insecure_string)。感谢 Jeremy 提供的库。 - Mike H-R

16

我有一些可能有用的提示:

  1. 你可以简单地执行以下操作:

 @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).first

注意:您忽略了可能还有更多符合条件的结果。如果您希望返回多个可能的行,则可以通过执行...来构建结果数组。

    @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).all

并处理它们所有。

  1. 返回的集合是一个哈希。如果@zonename指向其中一条记录,则可以执行以下操作:

 @zonename[:column_name] 

要引用一个名为“column_name”的字段。你不能使用@zonename.column_name(实际上,你可以使用一些元编程来装饰@zonename并使用帮助方法,但我们暂且忽略它)。

Sequel是一个优秀的接口,你学得越多,就会越喜欢它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接