假设我有一个查询某些表company.workers
的函数,例如(伪代码):
def sql_query(dept, prof, hireDate):
q = """SELECT *
FROM company.workers
WHERE department = {0}
AND profession = {1}
AND hire_date > {2}""".format(dept, prof, hireDate)
cur.execute(q)
return cur
如果我想仅允许用户在dept
和prof
上进行查询,hireDate
是可选的,该怎么办?这是我提出的解决方案:
def sql_query(dept, prof, *args):
if args:
q = """SELECT *
FROM company.workers
WHERE department = {0}
AND profession = {1}
AND hire_date > {2}""".format(dept, prof, args[0])
else:
q = """SELECT *
FROM company.workers
WHERE department = {0}
AND profession = {1} """.format(dept, prof)
cur.execute(q)
return cur
#the function could be called as so:
sql_query('20', 'Engineer', (2017-12-10))
但我认为这是次要的。如果我想允许多个可选 coloumns进行查询,该怎么办?如果我把它做成两个,我有4个选项可以处理,这是很多else-if
块。有更高效/更优雅的解决方案吗?
答案 0 :(得分:1)
您不会说出您正在使用的SQL DBMS,但这是一块接受三个变量的SQL Server样式代码块:
@dept
@prof
@hireDate
WHERE子句总是使用@dept和@prof,如果它不为null,则只使用@hireDate。
SELECT
*
FROM
company.workers
WHERE
department = @dept
AND
profession = @prof
AND
(
(
@hireDate IS NOT NULL AND hire_date = @hireDate
)
OR @hireDate IS NULL
)
然后,您可以根据需要使用相同的样式添加任意数量的其他选项变量,而不是为每个组合编写单独的SQL语句。
答案 1 :(得分:0)
类似问题here。你是对的,你真的不想手动生成语句。您可以使用字典使其更具动态性来改进当前代码:
def sql_query(**params):
q = "SELECT * FROM company.workers"
count=0
for i in non_require_param:
if count==0:
q += " WHERE {0} = {1} ".format(i, params[i])
else:
q += " AND {0} = {1} ".format(i, params[i])
count += 1
cur.execute(q)
return cur
此外,sqlite's execute cursor是值得研究的。它比自己格式化语句更清晰,并处理数据类型转换:
who = "Yeltsin"
age = 72
cur.execute("""select * from company.workers
where name_last=:name_last and age=:age""",
{"name_last": who, "age": age})