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()

我得到了一个错误:

错误: 提供的绑定数不正确。当前语句使用1,提供的绑定数为8。

我相信这是由于最初创建数据库造成的; 实际创建 DB 的模块有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个文件夹。我该怎么补救?

85657 次浏览

你试过这个吗:

for item in self.inventory_names:
t = (item,)
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", t)
self.cursor.close()

Execute ()期望一个序列(list,tuple)作为第二个参数

Cursor.execute()方法需要一个序列作为第二个参数。您提供的字符串恰好是8个字符长。

改用以下表格:

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])

Python 库引用: sqlite3光标对象

我花了半天时间试图弄明白为什么这样的东西会给我一个错误:

cursor.execute("SELECT * from ? WHERE name = ?", (table_name, name))

结果却发现表名为 无法参数化。希望这能帮助其他人节省一些时间。

引用(括号是这个意思吗?)什么?和括号一起看起来对我有用。我不断尝试(字面上)’?’但我一直得到

错误: 提供的绑定数不正确。当前语句使用0,提供1。

当我这么做的时候:

从 factoids WHERE key LIKE (?)中选择 fact

而不是:

从类似于“ ?”的关键字中选择事实

成功了。

这是某种蟒蛇2.6的东西吗?

试试看

execute("select fact from factoids where key like ?", "%%s%" % val)

您根本不需要围绕 ?进行任何包装,Python sqlite 将正确地将其转换为带引号的实体。

表示需要插入到数据库中的值的 cursor.execute参数应该是 tuple (序列)。然而,考虑一下这个例子,看看会发生什么:

>>> ('jason')
'jason'


>>> ('jason',)
('jason',)

第一个示例的计算结果是一个字符串; 因此表示单值元组的正确方法与第二个计算结果一样。无论如何,下面的代码将修复您的错误。

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item,))

还将 cursor.execute值参数作为字符串给出(这正是您正在做的) ,这将导致示例中的第一次求值,并导致出现错误。

项的每个元素都必须是元组。 假设名字是这样的:

names = ['Joe', 'Bob', 'Mary']

你应该这样做:

for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item, ))

通过使用(item) ,可以使它成为元组而不是字符串。

sqlite3模块支持 类型的参数占位符:

Qmark 风格

使用一个或多个 ?标记每个参数的位置,并提供参数列表或元组。例如:

curs.execute("SELECT weight FROM Equipment WHERE name = ? AND price = ?",
['lead', 24])

名叫时尚

对每个指定的参数使用 :par占位符,并提供一个 dict。例如:

curs.execute("SELECT weight FROM Equipment WHERE name = :name AND price = :price",
{name: 'lead', price: 24})

命名样式参数的优点是您不必担心参数的顺序,并且每个 :par可以在大型/复杂的 SQL 查询中多次使用。