2012-07-12 3 views
1

J'ai ce code:paramètre python sqlite3 passant question

conn = sqlite3.connect("testDB") 
curs = conn.cursor() 

curs.execute("CREATE TABLE IF NOT EXISTS testTable(col1 VARCHAR, col2 VARCHAR)") 
c1 = "value1" 
c2 = "value2" 
curs.execute("INSERT INTO testTable VALUES (?,?)", (c1, c2))#this works fine 
conn.commit() 

def inDB(curs, table, col, value): 
    curs.execute("SELECT * FROM ? WHERE ?=?",(table, col, value)) #problemis here 
    return bool(curs.fetchone()) 

print inDB(curs, "testTable", "col1", c1) 

Il me donne cette erreur:

Traceback (most recent call last): 
    File "test.py", line 16, in <module> 
    print inDB(curs, "testTable", "col1", c1) 
    File "test.py", line 13, in inDB 
    curs.execute("SELECT * FROM ? WHERE ?=?",(table, col, value)) 
sqlite3.OperationalError: near "?": syntax error 

Pourquoi cela ne fonctionne pas et comment puis-je résoudre ce problème?

Répondre

2

Je ne sais pas, mais je ne pense pas que vous pouvez utiliser des variables liées sur les noms de table ou de colonne ...

Essayez

curs.execute("INSERT INTO ? VALUES (?,?)", (testTable, c1, c2)) 

Je parie que cela ne fonctionnera pas. Dans ce cas, vous devez éviter d'utiliser ? sur les noms de table ou de colonne. Je préfère utiliser l'opérateur de concaténation pour rejoindre la chaîne comme dans Java c'est "+". Par exemple (style Java):

("INSERT INTO " + testTable + " VALUES (?,?)"); 
+0

Si vous utilisez la concaténation de chaîne n'est pas vulnérable pour SQLi si j'utilise du code pour une application web? – torayeff

+0

bien, peut-être ... mais je ne sais pas mieux quand vous voulez changer dynamiquement le nom de la table ... Si vous craignez l'injection SQL, vous pouvez créer plusieurs fonctions avec un nom de table fixe quelque chose comme: 'void addToTable1 (value1, value2) { ("INSERT INTO table1 VALEURS (?,?)", (valeur1, valeur2)); } ' ' void addToTable2 (valeur1, valeur2) { ("INSERT INTO table2 VALEURS (?,?)", (Valeur1, valeur2)); } ' – Slimer

+1

Quoi qu'il en soit, comment peut-on injecter le nom de la table ... Transmettez-vous le nom de la table comme argument à partir de l'entrée de l'utilisateur? Le nom de la table est supposé être une chose interne. Seule l'application elle-même doit connaître les noms des tables et seule l'application elle-même doit définir le paramètre (dans votre cas) 'testTable' à partir d'une liste connue. – Slimer

0

C'est tout ce que je pouvais extraire de la documentation:

http://www.sqlite.org/cintro.html

3.0 Binding Parameters and Reusing Prepared Statements

In SQLite, wherever it is valid to include a string literal, one can use a parameter in one of the following forms:

http://www.sqlite.org/c3ref/bind_blob.html

In the SQL statement text input to sqlite3_prepare_v2() and its variants, literals may be replaced by a parameter that matches one of following templates:

http://www.sqlite.org/lang_insert.html

SQLite INSERT

Vous ne pouvez probablement pas utiliser un nom de table paramétrées car [database-name.]table-name n'est pas une valeur littérale ordinaire (c'est pourquoi vous ne pouvez pas écrire une déclaration comme INSERT INTO 'foo'||'bar'||12 VALUES ...).

Ou peut-être que c'est quelque chose de complètement différent. :)