使用可选的“where”子句创建SQL查询函数

时间:2018-03-16 20:57:14

标签: python sql

假设我有一个查询某些表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

如果我想仅允许用户在deptprof上进行查询,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块。有更高效/更优雅的解决方案吗?

2 个答案:

答案 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})