2015-07-12 60 views
1

目前我通过python运行sql查询来从数据库中提取信息。SQL中的多个In语句通过python

我的代码是:

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

我现在想提出一个额外的报表,所以我的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模块。城市和国家列表可能会改变每个用户的输入,所以我不能把原始值放入SQL语句中。

+0

什么是'cur',并且您阅读了该类和'execute'方法的文档?你为什么要把你的琴弦声明为禁忌? '('london')=='london''如果你想创建一个元组文字,你需要使用逗号'('london',)' –

+0

这不是一个SQL问题。多个IN语句没有问题。这个问题必须与'cities'和'coun'绑定到适当的参数标记相关。 –

回答

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专家,所以我将不胜感激这种方法的任何缺点的反馈。