怪东西
看两段代码
1 | sql = "UPDATE users SET {} = ? WHERE username = ?" |
这个可以正常运行
运行流程如下
1 | sql = "UPDATE users SET {} = ? WHERE username = ?" |
经过 format
方法处理后,那么更新语句变为:
1 | UPDATE users SET type_name = ? WHERE username = ? |
此处有两个参数占位符 ?
,分别对应 datetime.now()
和 username
。
而在执行更新操作时,您提供了两个参数:
1 | cursor.execute(sql.format(type_name), (datetime.now(), username)) |
这里的 (datetime.now(), username)
是一个包含两个元素的元组,正好与 SQL 语句中的两个问号占位符相对应。因此,这次不会有参数数量不匹配的错误。
这里却会出现错误
1 | sql = "SELECT {} FROM users WHERE username = ?" # SQL查询模板,使用占位符代替字段名 |
1 | An error occurred: Incorrect number of bindings supplied. The current |
出现错误 “Incorrect number of bindings supplied. The current statement uses 1, and there are 19 supplied.” 的原因在于执行 SQL 查询时提供的参数数量与 SQL 语句中的参数占位符数量不符。
在这个例子中,SQL 查询语句为:
1 | SELECT {} FROM users WHERE username = ? |
经过 format
方法处理后,那么查询语句变为:
1 | SELECT type_name FROM users WHERE username = ? |
此时,查询语句中有 1 个参数占位符 ?
,因此在执行查询时应提供 1 个参数:
1 | cursor.execute(sql.format(type_name), (username,)) |
但示例代码中,括号内的 username
没有用逗号分隔成元组,而是直接跟在了括号后面,这可能导致 Python 将其视为单个字符组成的列表,从而产生了 19 个字符,每个字符被视为一个参数传递给了数据库查询方法,与查询所需的参数数量不符,引发了此错误。
正确的做法是将 username
作为元组传递:
1 | cursor.execute(select_sql.format(type_name), (username,)) |
在 Python 中,用一对圆括号 ( )
包裹的一系列值构成了一个元组。即使元组中只有一个元素,也需要在该元素后面加上一个逗号 ,
来明确表示这是一个元组,否则 Python 会将其视为一个单独的对象而非元组。
例如:
1 | # 正确创建单元素元组 |
在 SQL 查询和更新语句的例子中,(datetime.now(), username)
是一个包含两个元素的元组,无论有多少元素,只要在最后的元素后添加逗号,Python 都会将其解释为元组,这正是执行 SQL 语句时需要的参数格式。