代码之家  ›  专栏  ›  技术社区  ›  crystalattice

sqlite参数替换问题

  •  55
  • crystalattice  · 技术社区  · 16 年前

    使用sqlite3和python 2.5,我试图遍历一个列表,并根据项目的名称从数据库中提取项目的权重。

    我试过用“?”建议使用参数替换来防止SQL注入,但它不起作用。例如,当我使用:

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

    我得到错误:

    sqlite3.programmingeror:提供的绑定数不正确。当前语句使用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个绑定。我怎么修?

    8 回复  |  直到 6 年前
        1
  •  126
  •   Mike T    6 年前

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

    改为使用以下表单:

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

    python库参考:sqlite3 Cursor Objects .

        2
  •  49
  •   sth    15 年前

    我花了半天时间试图弄明白为什么这样的事情会给我带来错误:

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

    只为了找出那个表名 无法参数化 . 希望这能帮助其他人节省一些时间。

        3
  •  22
  •   jgtumusiime    13 年前

    论点 cursor.execute 它表示需要在数据库中插入的值应该是一个元组(序列)。然而,考虑这个例子,看看发生了什么:

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

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

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

    也给予 执行命令 作为字符串的值参数(这是您正在做的)会导致示例中的第一个评估,并导致您得到的错误。

        4
  •  2
  •   Blauohr    16 年前

    你试过这个吗?:

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

    cursor.execute()需要一个序列(list、tuple)作为第二个参数。(-gt;dDAA)

        5
  •  1
  •   kjikaqawej    15 年前

    引用(这就是帕伦斯的意思吗?)这个?和帕伦斯在一起似乎对我有用。我一直在尝试(字面上)“?”但我一直在

    ProgrammingError:提供的绑定数不正确。当前语句使用0,并且提供了1。

    当我这样做的时候:

    从factoids中选择事实,其中键类似(?)

    而不是:

    从factoids中选择事实,其中键类似“?”

    它奏效了。

    这是一些python 2.6的东西吗?

        6
  •  0
  •   Joey Nelson    11 年前

    项的每个元素都必须是元组。 假设名称如下:

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

    您应该执行以下操作:

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

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

        7
  •  0
  •   Mike T    6 年前

    这个 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查询中可以多次使用。

        8
  •  -5
  •   sth    14 年前

    尝试

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

    你不会把任何东西包在 ? 总之,python sqlite将正确地将其转换为带引号的实体。