2012-07-12 137 views
1

我有這樣的代碼:sqlite3的蟒蛇參數傳遞問題

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) 

它給我這個錯誤:

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 

爲什麼這不工作,我怎麼能解決這個問題?

回答

2

我不知道,但我不認爲你可以在表或列名稱使用綁定變量...

嘗試

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

我敢打賭,這是行不通的。在這種情況下,您需要避免在表名或列名上使用?。我寧願使用連接運算符來加入字符串,就像在Java中它是「+」一樣。例如(Java的風格):

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

如果使用字符串連接,如果我使用Web應用程序的代碼,是不是容易受到SQLi的影響? – torayeff 2012-07-12 21:53:36

+0

好吧,可能是...但我不知道更好的想法,當你想動態地改變表名...如果你害怕SQL注入,你可以創建多個函數,固定表名如下: 'void addToTable1(value1,value2){ (「INSERT INTO table1 VALUES(?,?)」,(value1,value2)); (','),(value1,value2));}。 }' – Slimer 2012-07-12 21:58:35

+1

無論如何,如何可以表名注入...你是否傳遞表名作爲參數從用戶輸入?表名應該是內部的東西。只有應用程序本身應該知道表名,並且只有應用程序本身應該從某個已知列表中設置參數(在你的情況下)'testTable'。 – Slimer 2012-07-12 22:15:38

0

這是所有我可以從文檔中提取:

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

你可能因爲[database-name.]table-name不是一個普通的文本值不能使用參數化的表名(這就是爲什麼你不能寫如下語句INSERT INTO 'foo'||'bar'||12 VALUES ...)。

或者它可能完全不同。 :)