You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用mysql-connector向MySQL表插入变量值时遭遇1136(21S01)列数不匹配错误的技术求助

解决MySQL插入时的1136 (21S01): Column count doesn't match value count at row 1错误

嘿,这个错误我太熟了——咱们直接点,问题出在你构造INSERT语句的方式上,数据库收到的值数量和你指定的字段数量对不上,所以才抛出这个报错。

错误原因拆解

你的pytania表有7个需要插入数据的字段:tresc_pytaniaodpowiedz_Aodpowiedz_Bodpowiedz_Codpowiedz_Dodpowiedz_truequestion_value。但你写的SQL语句里,VALUES (wartosci_do_bazy)相当于只把整个元组当成一个值传给了数据库,数据库自然会懵:“你告诉我要插7个字段,结果只给我一个值?”

修正方案(强烈推荐:参数化查询)

这是mysql-connector官方推荐的写法,既解决列数不匹配的问题,还能防止SQL注入攻击,一举两得:

mycursor = db.cursor()
wartosci_do_bazy = pytanie_mysql, odpowiedz_a, odpowiedz_b, odpowiedz_c, odpowiedz_d, odpowiedz_true_mysql, value_pytanie
# 用%s作为每个字段对应的占位符,数量和字段数严格一致
sql = "INSERT INTO pytania (tresc_pytania, odpowiedz_A, odpowiedz_B, odpowiedz_C, odpowiedz_D, odpowiedz_true, question_value) VALUES (%s, %s, %s, %s, %s, %s, %s)"
# 把变量元组作为execute的第二个参数传入,驱动会自动处理值的类型和格式
mycursor.execute(sql, wartosci_do_bazy)
db.commit()

原理很简单:%s是mysql-connector的参数占位符,execute方法会自动把你传入的元组wartosci_do_bazy里的每个元素对应到占位符上,保证值的数量和字段数完全匹配,同时还会帮你处理字符串转义,避免语法错误和注入风险。

不推荐的写法(仅作逻辑参考)

如果你非要用字符串拼接的方式(真的不建议),需要把元组里的每个元素拆解开,并且给字符串类型的值加上引号(数字类型不用),但这种方式很容易出问题:

mycursor = db.cursor()
wartosci_do_bazy = pytanie_mysql, odpowiedz_a, odpowiedz_b, odpowiedz_c, odpowiedz_d, odpowiedz_true_mysql, value_pytanie
# 手动把每个变量拆出来,字符串加单引号,数字直接写
sql = f"INSERT INTO pytania (tresc_pytania, odpowiedz_A, odpowiedz_B, odpowiedz_C, odpowiedz_D, odpowiedz_true, question_value) VALUES ('{pytanie_mysql}', '{odpowiedz_a}', '{odpowiedz_b}', '{odpowiedz_c}', '{odpowiedz_d}', '{odpowiedz_true_mysql}', {value_pytanie})"
mycursor.execute(sql)
db.commit()

⚠️ 警告:这种写法如果用户输入里包含单引号(比如用户输入I'm a student),会直接导致SQL语法错误,而且非常容易被SQL注入攻击,所以除非你完全控制输入内容,否则绝对不要用这种方式。

总结

核心问题就是你没有正确传递多个值,而是把整个元组当成了一个值。用参数化查询不仅能快速解决这个错误,还能让你的代码更安全、更健壮。

内容的提问来源于stack exchange,提问作者Damian Szmigielski

火山引擎 最新活动