【问题标题】:Using sqlite prepared statements with SELECT使用带有 SELECT 的 sqlite 准备好的语句
【发布时间】:2011-08-09 15:45:34
【问题描述】:

我正在从事一个小型项目,该项目组织人们的漫画书并将有关它们的元数据存储在 SQL 数据库中。为了正确起见,我使用准备好的语句而不是 Python 的内置字符串运算符,但我不能让它正常工作。这是我为说明我遇到的问题而编写的简短代码 sn-p:

#!/usr/bin/env python

import sqlite3

connection = sqlite3.connect("MyComicBox.db")

curs = connection.cursor()

curs.execute("CREATE TABLE IF NOT EXISTS comic_collection (id INTEGER PRIMARY KEY, series TEXT, publisher TEXT, issue TEXT, tags TEXT)")

connection.commit()

def addComic(series = "", publisher = "", issue = "", tags = ""):
    curs.execute("INSERT INTO comic_collection (series, publisher, issue, tags) VALUES(?, ?, ?, ?)", (series, publisher, issue, tags))
    connection.commit()

def search(attribute, val):
    """
    Do an SQL query for all comics where attribute LIKE val and return a list of them.
    """

#   cmd = "SELECT * from comic_collection WHERE %s LIKE '%s'" % (attribute, val)
#   curs.execute(cmd)

    cmd = "SELECT * from comic_collection WHERE ? LIKE ?"
    curs.execute(cmd, (attribute, val))

    results = []

    for comic in curs:
        results.append(comic)

    return results

addComic(series = "Invincible Iron Man", issue = "500", publisher = "Marvel Comics", tags = "Iron Man; Spider-Man; Mandarin")


searchResults = search("issue", "500")

for item in searchResults:
    print item

我的问题在于搜索功能。除非我使用 ? 替换执行 cmd 的两行,否则查询不会返回任何内容使用 Python 的内置字符串运算符执行 cmd 的两行(已注释掉)的运算符。谁能帮我弄清楚我做错了什么?

【问题讨论】:

  • 这在技术上只是一个“参数化语句”,而不是“准备好的语句”。 “准备语句”通常是“参数化语句”(除非它没有参数),但解析语句实例的句柄会被保留并重用,而不是每次都传递 SQL 文本。 AFAIK,Python 的 SQLite 模块不支持准备好的语句。

标签: python sqlite


【解决方案1】:

您不能将占位符用于列名 - 它们仅用于值。所以这会起作用:

cmd = "SELECT * from comic_collection WHERE %s LIKE ?" % attribute
curs.execute(cmd, (val,))

【讨论】:

    【解决方案2】:

    您对attribute 的使用是错误的。想象一下? 已经包含了它的放弃''s。

    一种方法是这样做:

    cmd = "SELECT * from comic_collection WHERE %s LIKE ?" % attribute
    curs.execute(cmd, val)
    

    但您绝对必须确保该属性不是来自不受信任的来源,或者它只有有效值,可能来自

    assert attribute in ('series', 'publisher', 'issue', 'tags')
    

    【讨论】:

      【解决方案3】:

      根据我对 sqlite C api 中准备好的语句的回忆,您可能必须这样写:

      cmd = "SELECT * from comic_collection WHERE ?1 LIKE ?2"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-18
        • 1970-01-01
        • 2015-06-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多