SQLite3数据库使用变量插入

时间:2015-11-05 19:08:29

标签: ruby sqlite

我正在编写一个将结果导出到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使用变量。

1 个答案:

答案 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)或者将括号留下来。