2010-11-16 33 views
4

Lors de l'utilisation d'instructions préparées avec des paramètres nommés dans SQLite (en particulier avec le module python sqlite3 http://docs.python.org/library/sqlite3.html) est-il possible d'inclure des valeurs de chaîne sans avoir à les placer autour d'elles?sqlite/python - paramètres nommés sans entourer de guillemets?

J'ai ceci:

columnName = '''C1''' 
cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName}) 

Et il semble que le SQL je finis avec est ceci:

SELECT DISTINCT('C1') FROM T1 

qui n'est pas très bien sûr, ce que je veux vraiment est :

SELECT DISTINCT(C1) FROM T1 . 

Est-il possible d'inviter la méthode execute pour interpréter les arguments fournis de telle sorte qu'il n » t envelopper des citations autour d'eux?

J'ai écrit un petit programme de test pour explorer ce bien ainsi pour ce que ça vaut la voici:

import sys 
import sqlite3 
def getDatabaseConnection(): 
    DEFAULTDBPATH = ':memory:' 

    conn = sqlite3.connect(DEFAULTDBPATH, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) 
    conn.text_factory = str 

    return conn 

def initializeDBTables(conn): 
    conn.execute(''' 
    CREATE TABLE T1(
     id INTEGER PRIMARY KEY AUTOINCREMENT, 
     C1 STRING);''') 
    cur = conn.cursor() 
    cur.row_factory = sqlite3.Row # fields by name 

    for v in ['A','A','A','B','B','C']: 
     cur.execute('''INSERT INTO T1 values (NULL, ?)''', v) 

    columnName = '''C1''' 
    cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName}) 

    #Should end up with three output rows, in 
    #fact we end up with one 
    for row in cur: 
     print row 


def main(): 
    conn = getDatabaseConnection() 
    initializeDBTables(conn) 

if __name__ == '__main__': 
    main() 

serait intéressé d'entendre parler de toute façon de manipuler la méthode d'exécution pour permettre que cela fonctionne.

Répondre

3

Dans SELECT DISTINCT(C1) FROM T1 le C1 n'est pas une valeur de chaîne, c'est un morceau de code SQL. Les paramètres (échappés dans execute) sont utilisés pour insérer des valeurs, pas des morceaux de code.

0

Vous utilisez des liaisons et les liaisons ne peuvent être utilisées que pour les valeurs, pas pour les noms de table ou de colonne. Vous devrez utiliser l'interpolation string/formstting pour obtenir l'effet que vous voulez, mais cela vous laisse ouvert aux attaques par injection SQL si le nom de la colonne provient d'une source non fiable. Dans ce cas, vous pouvez nettoyer la chaîne (par exemple, autoriser uniquement des caractères alphanumériques) et utiliser l'interface de l'autorisateur pour vérifier qu'aucune activité inattendue ne se produira.