2011-08-09 23 views
3

私は、人の漫画を編成し、それらに関するメタデータをSQLデータベースに格納する小さなペットプロジェクトに取り組んでいます。正しさのために、私はPythonの文字列演算子の代わりにprepared statementsを使っていますが、正しく動作させることはできません。これは私が持っている問題を説明するために作ったコードの簡単なスニペットです: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を使用して2つの行を置き換えない限り、クエリは何も返しません? Pythonの組み込みの文字列演算子を使用してcmdを実行する2行(コメントアウトされた行)を持つオペレータです。誰でも私が間違っていることを理解する手助けができますか?

+1

これは技術的には「パラメータ化された文」であり、「準備文」ではありません。 'prepared statement'は通常はパラメータ化された文ですが(パラメータがない場合を除く)、毎回渡されるSQLテキストではなく、解析された文のインスタンスへのハンドルが保持され、再利用されます。 AFAIKは、PythonのSQLiteモジュールでは準備された文がサポートされていません。 – Sam

答えて

2

attributeの使用は間違っています。 ?にはすでにその払い戻し額が含まれているとします('')。

、このようにそれを行うことであろう一つの方法:

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は= "?comic_collectionからWHERE 1 LIKE SELECT * 2?"