2011-08-09 76 views
3

我正在制作一个小型宠物项目,该项目组织人们的漫画并在SQL数据库中存储有关它们的元数据。为了正确,我使用了准备好的语句而不是Python内置的字符串运算符,但我无法完全正确地使用它。这是我用来说明我遇到的问题的简短代码片段:在SELECT语句中使用sqlite预处理语句

#!/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。任何人都可以帮我弄清楚我做错了什么吗?

+1

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

回答

2

您的用法attribute是错误的。想象一下?已经包含了它的趋势'' s。

一种方法是这样来做:

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

,但你绝对要保证属性不是来自不受信任的来源在这里还是它只有有效值,也许是

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

修复它。谢谢! – NapoleonBlownapart

7

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

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

从我记得在SQLite的C API预处理语句,你可以将它写这样的:

CMD = “SELECT * FROM comic_collection WHERE 1 LIKE 2?”