如何将参数化的sql查询放入变量然后在Python中执行?

Wil*_*ill 7 python sql

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

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3)
Run Code Online (Sandbox Code Playgroud)

这样它就可以防止sql注入.我的问题是,是否有办法将查询放入变量然后执行它?我尝试过以下示例但收到错误.是否有可能做到这一点?

sql="INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(sql)
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 15

这是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.
Run Code Online (Sandbox Code Playgroud)

因此,execute最多需要3个参数(args是可选的).如果给出了args,则预期它是一个序列.所以

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)
Run Code Online (Sandbox Code Playgroud)

不会起作用,因为

cursor.execute(*sql_and_params)
Run Code Online (Sandbox Code Playgroud)

将元组sql_and_params扩展为4个参数(同样,执行只需要3个参数).

如果你真的必须使用

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
Run Code Online (Sandbox Code Playgroud)

然后你必须把它分开来喂它cursor.execute:

cursor.execute(sql_and_params[0],sql_and_params[1:])
Run Code Online (Sandbox Code Playgroud)

但我觉得使用两个变量感觉更愉快:

sql = "INSERT INTO table VALUES (%s, %s, %s)"
args= var1, var2, var3
cursor.execute(sql, args)
Run Code Online (Sandbox Code Playgroud)


Ant*_*sma 6

你很接近。

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)
Run Code Online (Sandbox Code Playgroud)

星号意味着该变量不被视为一个参数,而是解包为多个参数。

  • @bzupnick 使用简单的字符串格式(`%` 运算符)或替换,可能会允许 SQL 注入,更不用说在需要时无法向文字添加引号。参数化查询远优于格式化/替换查询。 (2认同)