我正在编写一个将结果导出到SQLite数据库的脚本。当我使用变量时,我无法使代码工作。
以下是摘录:
require 'sqlite3'
require 'shodan'
table_name = "#{Date.today.strftime("%B")}#{Time.now.year}_Findings"
db = SQLite3::Database.new "shodan_test.db"
db.execute ("CREATE TABLE #{table_name} (ip string , ports string)")
results = api.host(target)
ip = results["ip_str"].to_s
ports = results["ports"].to_s
db.execute ("insert into #{table_name} (ip, ports) values (#{ip}, #{ports})")
代码在最后一行失败。我可以删除变量和代码工作。我有点困惑,因为CREATE TABLE使用变量。
答案 0 :(得分:1)
你的问题是你没有引用你的字符串。结果是SQLite看到像
这样的东西insert into ... values (192.168.0.6, whatever is in ports)
并且这不是有效的SQL。
SQLite3::Database#execute
了解占位符,因此您应该使用它们:
db.execute("insert into #{table_name} (ip, ports) values (?, ?)", ip, ports)
查询中的占位符(?
)将替换为其值的正确引用和转义版本。使用占位符避免了使用SQL字符串插值困扰的所有常见引用和注入问题。
另请注意,我删除了execute
和(
之间的空格。如果你在那里放置一个空格,那么Ruby认为你的“方法调用括号”实际上是“表达式括号括号”,它会抱怨不理解这些逗号正在做什么。如果你只传递一个参数(例如在db.execute ("CREATE ...")
中)那么它将无关紧要,因为括号被有效地忽略但是当有多个参数时它确实很重要。在任何情况下,o.m (arg)
都是一个不好习惯,你应该说o.m(arg)
或者将括号留下来。