假設我有一個SQLite表是這樣的:如何撰寫此查詢?
Id|B|C|D
而且我有一個包含Id
一些值的列表。也許[1,3,45,67](類似的東西)。
我想獲得列表中Id的行,其B
值大於5,並最終命令C
。
我認爲我爲此編出的標題太糟糕了,如果你能想到更好的標題,請修改它。
假設我有一個SQLite表是這樣的:如何撰寫此查詢?
Id|B|C|D
而且我有一個包含Id
一些值的列表。也許[1,3,45,67](類似的東西)。
我想獲得列表中Id的行,其B
值大於5,並最終命令C
。
我認爲我爲此編出的標題太糟糕了,如果你能想到更好的標題,請修改它。
相關問題,從中我會偷亞歷馬爾泰利的答案:
Parameter substitution for a SQLite "IN" clause
這是我所創建的數據:
sqlite> create table x(a,b,c,d);
sqlite> insert into x values(1, 10, 2, null);
sqlite> insert into x values(2, 10, 3, null);
sqlite> insert into x values(3, 10, 4, null);
而Python來取,
>>> ids = [2, 3]
>>> query = "SELECT b, c, d FROM x WHERE a IN ({0}) AND b > 5 ORDER BY c".format(','.join('?' for i in ids))
>>> query
'SELECT b, c, d FROM x WHERE a IN (?,?) AND b > 5 ORDER BY c'
>>> conn.execute(query, ids).fetchall()
[(10, 3, None), (10, 4, None)]
我不知道蟒蛇和SQLite之間的API,但是這個僞代碼應該有所幫助:
list_id = [1,3,45,67]
ids = ",".join(["%s" % el for el in list_id])
print 'SELECT * FROM table WHERE B>5 AND ID IN (%s) ORDER BY C DESC' % (ids)
請記住,你既不應該使用'SELECT *'你也不應該建立使用字符串連接查詢(使用預處理語句這裏)。 – 2011-03-21 14:22:56
假設ids_list是你的ID和表名的列表是你的表:
c = sqlite3.connect('foo').cursor()
c.execute("""
select Id, B, C, D
from tablename
where
Id in (%s) and
B >= 5
order by C
""" % ",".join(str(int(id)) for id in ids_list))
%s
替換是不好的做法,因爲受SQL注入。應該使用?
來代替,但它似乎不適用於in
子句。因此,STR(INT(ID))絕招,爲「的sanitize」(或檢查)的ID值(會失敗,如果沒有有效的值)
爲什麼使用佔位符時可以正確使用它的技巧? – 2011-03-21 15:39:39
是的,如果列表的長度足夠小,它會更好地動態地構建佔位符,就像你提出的那樣。佔位符的主要目的是防止SQL注入,如果ids列表不是來自用戶,而是另一個查詢,例如,應該沒問題。請注意,在後一種情況下,聯合會更好:) – 2011-03-21 15:44:28
我會用以下內容:
ids = [1, 3, 45, 67]
cnx = sqlite3.connect('my_database.db')
cursor = cnx.cursor()
cursor.execute("""
SELECT Id, B, C, D FROM table
WHERE Id IN (%s) AND B > 5 ORDER BY C
""" % ','.join('?' * len(ids)), tuple(ids))
results = cursor.fetchall()
+1,但該方案在超過SQLITE_MAX_VARIABLE_NUMBER時將失敗,即語句中佔位符的數量(默認值爲999)。 – XORcist 2011-03-21 15:35:02