0

我目前正在根据用户的输入构建 SQL 查询。可以在此处看到如何完成此操作的示例:

def generate_conditions(table_name,nameValues):
    sql = u""
    for field in nameValues:
        sql += u" AND {0}.{1}='{2}'".format(table_name,field,nameValues[field])
    return sql

search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"

if "Enhet" in args:
    search_query += generate_conditions("e",args["Enhet"])
c.execute(search_query)

由于每次我无法在执行调用中插入值时 SQL 都会更改,这意味着我应该手动转义字符串。但是,当我搜索每个人都指向执行...

我对生成查询的方式也不满意,所以如果有人对另一种方式有任何想法,那也很棒!

4

1 回答 1

2

你有两个选择:

  1. 切换到使用SQLAlchemy;它将使生成动态 SQL 更加 Pythonic确保正确引用。

  2. 由于您不能对表名和列名使用参数,因此您仍然必须使用字符串格式来将它们包含在查询中。另一方面,您的值应始终使用 SQL 参数,前提是数据库可以准备语句。

    直接从用户输入中插入表名和列名是不可取的,以这种方式注入任意 SQL 语句容易了。对照您接受的此类名称列表验证表和列名称。

    因此,以您的示例为基础,我将朝这个方向发展:

    tables = {
        'e': ('unit1', 'unit2', ...),   # tablename: tuple of column names
    }
    
    def generate_conditions(table_name, nameValues):
        if table_name not in tables:
            raise ValueError('No such table %r' % table_name)
        sql = u""
        params = []
        for field in nameValues:
            if field not in tables[table_name]:
                raise ValueError('No such column %r' % field)
            sql += u" AND {0}.{1}=?".format(table_name, field)
            params.append(nameValues[field])
        return sql, params
    
    search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"
    
    search_params = []
    if "Enhet" in args:
        sql, params = generate_conditions("e",args["Enhet"])
        search_query += sql
        search_params.extend(params)
    c.execute(search_query, search_params)
    
于 2012-09-12T13:50:58.973 回答