SQL中的多个In语句通过python

时间:2015-07-12 11:44:38

标签: python sql sqlite

目前我正在通过python运行sql查询以从数据库中提取信息。

我的代码是:

cities = ('London')
sql = 'SELECT * FROM Customers WHERE City IN ({});'
cur.execute(sql, cities)

我现在想要添加一个额外的IN语句,所以我的sql查询看起来像这样:

coun = ('uk')
cities = ('london')
sql = 'SELECT * FROM Customers WHERE City IN ({}) AND Country IN ({});'
cur.execute(sql, cities, coun)

这段代码不起作用,因为我在execute命令中指定了两个变量列表,但我也想知道SQL是否不喜欢有两个IN语句?我试图单独测试它,但它不喜欢两个IN语句。

有没有办法让这段代码有效?我正在运行python 2.7和sqlite3模块。 city和coun列表可能会针对每个用户输入进行更改,因此我不能将原始值放入SQL语句中。

1 个答案:

答案 0 :(得分:0)

这样做的一种方法是首先建立正确数量的所需数量?'选择查询字符串中的值,使用councities元组的长度(我将它们设置为元组而不是问题中显示的带括号的字符串)。

这不容易受到SQL注入攻击,因为您只在查询用户数据时格式化问号字符。

之后,您只需合并councities元组,并将其传递给execute

import sqlite3
from itertools import repeat

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create TABLE Customers (Name, City, Country)")

companylist = [
    ("Microsoft", "Redmond", "United States"),
    ("BSkyB", "London", "UK"),
    ("Freesat", "London", "UK"),
    ("BBC", "Manchester", "UK"),
    ("Aqsacom", "Melbourne", "Australia"),
    ('Blah', 'London', 'Canada')
]

# multiple case
#coun = ('UK', 'Australia')
#cities = ('London', 'Melbourne')

# single case
coun = ('UK',)
cities = ('London',)


def makeqmarks(i):
    return ', '.join(repeat('?', i))

for company in companylist:
    cur.execute("INSERT INTO Customers Values (?,?,?)", company)

sql = 'SELECT * FROM Customers WHERE City IN (%s) AND Country IN (%s);' \
% (makeqmarks(len(cities)), makeqmarks(len(coun)))

cur.execute(sql, cities + coun)

for res in cur.fetchall():
    print(res)

我不是一名SQL专家,所以我很感激这种方法的任何缺点的反馈。