如何将变量传递到 Ruby 中的准备语句?

How do I pass a variable into a prepared statement in Ruby?

我在 Ruby 中有一个方法可以查询数据库并打印出一些数据,我正在尝试使用准备好的语句。

下面是没有预编译语句的运行方法:

def print_state_speakers(*states)
  puts "STATE SPEAKERS"
  state_string = "'#{states.*"', '"}'"
  state_speakers = $db.execute("
    SELECT name, location 
    FROM congress_members 
    WHERE location IN (#{state_string})
    ORDER BY location")
  state_speakers.each { |rep, location| puts "#{rep} - #{location}" }
end

这是我使用准备好的语句对相同方法的尝试:

def print_state_speakers(*states)
  puts "STATE SPEAKERS"
  state_string = "'#{states.*"', '"}'"
  begin
    pst = $db.prepare "SELECT name, location 
    FROM congress_members 
    WHERE location IN (?)
    ORDER BY location"
    state_speakers = pst.execute state_string
  end
  state_speakers.each { |rep, location| puts "#{rep} - #{location}" }
end

这里是我调用方法的地方:

 print_state_speakers('NJ', 'NY' , 'ME', 'FL', 'AK')

当我 运行 使用第一种方法的文件时它显示数据,当我使用第二种方法时,它什么也不显示。它不会引发错误。我觉得语法需要不同才能解释传入的字符串,但我一直在网上搜索并弄乱了一段时间,但无法让它工作。任何有关如何修复准备好的语句的见解都将不胜感激。

当你这样说时:

pst = $db.prepare "SELECT name, location 
FROM congress_members 
WHERE location IN (?)
ORDER BY location"
state_speakers = pst.execute state_string

pst.execute 调用将转义并像任何其他字符串一样引用 state_string。但是您的 state_string 并不是真正的单个字符串,它是一个 SQL 列表,表示为 (Ruby) 字符串,因此您最终会双引号所有内容。

一个简单的解决方案是使用字符串插值来添加适当数量的占位符,然后让 SQLite3::Statement 自行处理所有引用:

placeholders = ([ '?' ] * states.length).join(',')
pst = $db.prepare "SELECT name, location 
FROM congress_members 
WHERE location IN (#{placeholders})
ORDER BY location"
state_speakers = pst.execute states

这种字符串插值的使用是非常安全的,因为您确切地知道 placeholders.

中的内容