2012-09-11 34 views
1

簡單的問題,可能有一個非常簡單的答案。我正在將格式爲「2012-06-10」的日期字符串從Python腳本寫入TEXT列。如何防止sqlite將字符串評估爲數學表達式?

例如

 
cur.execute("CREATE TABLE tbl(date TEXT, ...)") 

cur.execute('INSERT INTO tbl VALUES(%s)' % (str(date[i])), ...) 

腳本實際上是評估日期字符串,因此「2012-06-10」被寫入到表「1996年」。從閱讀文檔,我猜這與類型親和力有關,但我不知道如何重寫,甚至爲什麼字符串將被評估。

回答

9

兩種方式:

  • 通過使用參數化查詢:cur.execute("INSERT INTO tbl VALUES (?), [str(date[i])])。這是最好的方法。這樣做。第二種方法只是被列入後人。
  • 通過引用該值(注意:幾乎可以肯定在幾乎所有情況下都是錯誤的):cur.execute("INSERT INTO tbl VALUES ('%s')" %(str(date[i]),)。此方法並不理想,因爲除非您小心,否則您將很容易受到SQL注入的影響。

要理解爲什麼這是怎麼回事,想象你的代碼發送到SQLite的查詢:

INSERT INTO tbl VALUES (2012-06-10); 

哪些SQL引擎正確的計算結果爲:

INSERT INTO tbl VALUES (1996); 

引述值將解決此問題:

INSERT INTO tbl VALUES ('2012-06-10'); 

但是如果值中包含某些字符(字符如'或空字節),則會導致問題。

但是,使用參數化查詢時,這些值將與查詢分開發送,因此不會被誤解。

+3

爲什麼第一種方法更好?由於[SQL注入](http://en.wikipedia.org/wiki/SQL_injection)。 –

+0

這完美的作品。 +1的解釋。 – acpigeon

+0

如果這些值已經是字符串(或Python的sqlite3模塊會自動轉換爲字符串的'datetime.date'對象),則'str'調用是多餘的。 – dan04