SQLite 参数替换问题
我在用Python 2.5和SQLite3的时候,想要遍历一个列表,从数据库中根据物品的名字获取它的重量。
我试着用“?”这种参数替换的方法来防止SQL注入,但它没有效果。比如,当我使用:
for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", item)
self.cursor.close()
我遇到了这个错误:
sqlite3.ProgrammingError: 绑定的数量不正确。当前语句需要1个,但提供了8个。
我觉得这个问题可能和数据库的初始创建有关;我做的那个创建数据库的模块确实有8个绑定。
cursor.execute("""CREATE TABLE Equipment
(id INTEGER PRIMARY KEY,
name TEXT,
price INTEGER,
weight REAL,
info TEXT,
ammo_cap INTEGER,
availability_west TEXT,
availability_east TEXT)""")
不过,当我使用不太安全的“%s”替换每个物品名字时,它就能正常工作。像这样:
for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = '%s'" % item)
self.cursor.close()
我搞不明白为什么它会认为我有8个绑定,而我其实只调用了一个。我该怎么解决这个问题呢?
9 个回答
34
在使用 cursor.execute
时,你需要插入到数据库中的值应该用一个元组(序列)来表示。不过看看这个例子,看看发生了什么:
>>> ('jason')
'jason'
>>> ('jason',)
('jason',)
第一个例子计算出来的是一个字符串;所以正确表示单个值元组的方式是第二个例子那样。不管怎样,下面的代码可以帮你修复这个错误。
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item,))
另外,把 cursor.execute
的值参数作为字符串传入(这正是你现在做的)会导致第一个例子的计算结果,从而出现你遇到的错误。
83
我花了半天的时间在想,为什么像这样的代码会出错:
cursor.execute("SELECT * from ? WHERE name = ?", (table_name, name))
结果发现,表的名字不能用参数来设置。希望这个信息能帮助其他人节省一些时间。
167
Cursor.execute()
方法的第二个参数应该是一个序列(可以理解为一组数据),而你提供的是一个字符串,刚好有8个字符长。
请使用下面的格式:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])
Python库参考:sqlite3 游标对象。