74

Python 2.5 で SQLite3 を使用して、リストを反復処理し、アイテムの名前に基づいてデータベースからアイテムの重量を取得しようとしています。

「?」を使ってみました。SQL インジェクションを防ぐためにパラメーター置換が提案されましたが、機能しません。たとえば、次を使用する場合:

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

エラーが発生します:

sqlite3.ProgrammingError: 提供されたバインディングの数が正しくありません。現在のステートメントは 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()

1つしか呼び出していないのに、8つのバインドがあると考える理由がわかりません。どうすれば修正できますか?

4

8 に答える 8

153

このCursor.execute()メソッドは、2 番目のパラメーターとしてシーケンスを想定しています。たまたま 8 文字の長さの文字列を指定しています。

代わりに次のフォームを使用してください。

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

Python ライブラリ リファレンス: sqlite3 Cursor Objects

于 2008-10-23T08:41:23.167 に答える
30

cursor.executeデータベースに挿入する必要がある値を表すその引数は、タプル (シーケンス) である必要があります。ただし、次の例を検討して、何が起こっているかを確認してください。

>>> ('jason')
'jason'

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

最初の例は代わりに文字列に評価されます。したがって、単一の値のタプルを表す正しい方法は、2 番目の評価のとおりです。とにかく、以下のコードでエラーを修正してください。

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

また、cursor.execute値の引数を文字列として指定すると(これが実行中です)、例の最初の評価が行われ、エラーが発生します。

于 2011-09-05T08:51:03.867 に答える
2

これを試しましたか?:

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

cursor.execute()は、2番目のパラメーターとしてシーケンス(list、tuple)を想定しています。(-> ddaa)

于 2008-10-23T08:32:39.330 に答える
1

引用(それが括弧の意味ですか?) ? with parens は私にとってはうまくいくようです。私は(文字通り)「?」で試し続けました。しかし、私は得続けました

ProgrammingError: 提供されたバインディングの数が正しくありません。現在のステートメントは 0 を使用しており、1 が指定されています。

私がしたとき:

SELECT ファクト FROM ファクトイド WHERE キー LIKE (?)

それ以外の:

SELECT ファクト FROM ファクトイド WHERE キー LIKE '?'

出来た。

これはpython 2.6のものですか?

于 2010-02-10T15:54:12.650 に答える
0

items の各要素はタプルでなければなりません。名前を仮定すると、次のようになります。

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

次のことを行う必要があります。

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

(item, ) を使用すると、文字列ではなくタプルになります。

于 2014-05-19T04:45:45.763 に答える
-6

試す

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

何もラップしないでください?。Pythonsqliteはそれを引用符で囲まれたエンティティに正しく変換します。

于 2010-07-27T18:31:20.773 に答える