我有一个示例字符串“Canon PowerShot 12.1-Megapixel”,当我运行以下代码时,它似乎失败了:
db.execute "CREATE TABLE IF NOT EXISTS Products( id INTEGER PRIMARY KEY, stockID INTEGER, Name TEXT )"
id = 12345
name = "Canon PowerShot 12.1-Megapixel"
db.execute( "INSERT INTO Products ( stockID, Name ) VALUES ( #{id}, #{name} )" )
错误代码为:
C:/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.6-x86-mingw32/lib/sqlite3/d
atabase.rb:91:in `initialize': near "PowerShot": syntax error
(SQLite3::SQLExcep tion)
from C:/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.6-x86-mingw32/
lib/sqlite3/database.rb:91:in `new'
from C:/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.6-x86-mingw32/
lib/sqlite3/database.rb:91:in `prepare'
from C:/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sqlite3-1.3.6-x86-mingw32/
lib/sqlite3/database.rb:134:in `execute'
from E:/Documents/Cowboom/scraping/DBDOTDList.rb:48:in `<main>'
知道为什么它会在“PowerShot”之后消失吗?
最佳答案
您正在创建的字符串周围没有引号。所以字符串实际上是这样的:
"INSERT INTO Products ( stockID, Name ) VALUES ( 12345, Canon PowerShot 12.1-Megapixel )"
如您所见,这是无效的 SQL;它将尝试将 Canon PowerSho 12.1-Megapixel
解释为 SQL 语句的一部分,而不是字符串。
您可以尝试通过在变量插值周围加上引号来解决此问题:
db.execute( "INSERT INTO Products ( stockID, Name ) VALUES ( #{id}, '#{name}' )" )
但是,这通常是个坏主意。如果字符串最终包含 '
,那么这将结束 SQL 语句中的字符串,从而导致错误(或者更糟,如果攻击者这样做,则会出现 SQL injection 漏洞;参见 this comic for an amusing example ).您通常应该避免尝试通过插入或附加字符串来构建 SQL 查询;你可能认为你可以过滤掉或引用错误的字符,但这实际上很难做到。
相反,您应该为传递到 SQL 语句中的任何可变数据使用绑定(bind)参数:
db.execute( "INSERT INTO Products ( stockID, Name ) VALUES ( ?, ? )", [id, name])
参见 sqlite3-ruby documentation获取更多信息和示例。
关于ruby - 将 Ruby 字符串插入 Sqlite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13462112/