如何将变量传递到 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
.
中的内容
我在 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
.