2010-11-16 59 views
4

在SQLite中使用具有命名參數的預準備語句時(具體來說,使用python sqlite3模塊http://docs.python.org/library/sqlite3.html)是否有包含字符串值而不會在其周圍引用引號的問題?sqlite/python - 命名參數不包含引號?

我有這樣的:

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

而且似乎我結束了與SQL是這樣的:

SELECT DISTINCT('C1') FROM T1 

這是沒有多大用處,當然,我真正想要的是:

SELECT DISTINCT(C1) FROM T1 . 

是否有任何方式來提示執行方法來解釋所提供的參數以這樣的方式,它不」不要在他們周圍包裹報價?

我寫了一個小的測試程序來探索這個完全所以它的價值在這裏,它是:

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() 

是否有興趣反正操縱的執行方法,使這項工作的聽到。

回答

3

SELECT DISTINCT(C1) FROM T1C1不是字符串值,它是一段SQL代碼。參數(在execute中轉義)用於插入值,而不是代碼段。

0

您正在使用綁定,綁定只能用於值,而不能用於表或列名。您將不得不使用字符串插值/窗體來獲得所需的效果,但如果列名來自不受信任的源,則會導致SQL注入攻擊。在這種情況下,您可以清理字符串(例如,只允許字母數字)並使用授權人界面來檢查是否不會發生意外活動。