
当根据用户权限动态决定是否添加WHERE条件时,需将SQL参数与查询语句解耦——通过独立的params变量控制占位符绑定,避免“未使用全部参数”错误。
当根据用户权限动态决定是否添加where条件时,需将sql参数与查询语句解耦——通过独立的`params`变量控制占位符绑定,避免“未使用全部参数”错误。
在Python中使用mysql-connector-python(或类似驱动)执行参数化查询时,cursor.execute()要求传入的参数元组必须与SQL语句中的%s占位符数量严格一致。原代码中,无论WHERE子句是否存在,都统一传入(current_user,),导致无WHERE分支时出现 ProgrammingError: Not all parameters were used in the SQL statement 错误。
正确的做法是将查询逻辑与参数绑定分离:仅在SQL含占位符时才提供对应参数。以下是优化后的实现:
def get_expenses_by_type(self, current_user):
try:
cursor = self.main_db.cursor(dictionary=True)
if self.check_user_level(current_user) == 0:
query = """
SELECT Date, Type, SUM(Price * Quantity) AS TotalAmount
FROM ExpenseTable
WHERE UserID = %s
GROUP BY Date, Type;
"""
params = (current_user,) # ✅ 1个占位符 → 1个参数
else:
query = """
SELECT Date, Type, SUM(Price * Quantity) AS TotalAmount
FROM ExpenseTable
GROUP BY Date, Type;
"""
params = () # ✅ 0个占位符 → 空元组
cursor.execute(query, params) # ✅ 参数与SQL严格匹配
results = cursor.fetchall()
return results
except Exception as error:
raise error
finally:
if 'cursor' in locals():
cursor.close() # ✅ 建议移入finally确保关闭
关键改进点说明:
- ✅ 参数解耦:
params变量随query动态变化,杜绝占位符与参数数量不一致; - ✅ 安全性保障:仍全程使用参数化查询,避免SQL注入风险;
- ✅ 资源健壮性:添加
finally块确保游标始终关闭(即使发生异常); - ✅ 可扩展性:若后续需支持多条件(如按日期范围过滤),只需扩展
params元组与对应%s即可,逻辑清晰易维护。
⚠️ 注意:切勿拼接字符串构造SQL(如
"WHERE UserID = " + str(current_user)),这会引入严重安全漏洞。始终依赖驱动的参数化机制处理动态值。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











