如何将参数化的SQL查询放入变量并在Python中执行?

11 投票
4 回答
55480 浏览
提问于 2025-04-15 15:25

我明白在Python中格式化SQL查询的正确方法是这样的:

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3)

这样可以防止SQL注入攻击。我的问题是,有没有办法把查询放在一个变量里,然后再执行它?我试过下面的例子,但收到了错误。这样做是可能的吗?

sql="INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(sql)

4 个回答

1

这个方法对我有效。我使用pyodbc来查询Microsoft SQL Server。

cusotmer_list = ['ABC', '123']

# parameterized query placeholders
placeholders = ",".join("?" * len(customer_list))

# query table
query = 
"""
SELECT
[ID],
[Customer]
FROM xyz.dbo.abc
WHERE [Customer] IN (%s)
""" % placeholders

# read query results in pandas dataframe
df = pd.read_sql(sql=query, con=cnxn, params=customer_list)
6

你已经很接近了。

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)

星号(*)的意思是这个变量不是作为一个参数来处理的,而是要把它拆开,变成多个参数。

25

这里是cursor.execute的调用方式:

Definition: cursor.execute(self, query, args=None)

    query -- string, query to execute on server
    args -- optional sequence or mapping, parameters to use with query.

所以execute最多可以接受3个参数(args是可选的)。如果提供了args,它应该是一个序列。

因此,

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)

这样做是行不通的,因为

cursor.execute(*sql_and_params)

会把sql_and_params这个元组展开成4个参数(而execute只期待3个)。

如果你真的必须使用

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3

那么在传给cursor.execute的时候,你需要把它拆开:

cursor.execute(sql_and_params[0],sql_and_params[1:])

不过我觉得用两个变量会更简单一些:

sql = "INSERT INTO table VALUES (%s, %s, %s)"
args= var1, var2, var3
cursor.execute(sql, args)

撰写回答