You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python开发MySQL搜索按钮触发1064 SQL语法错误排查求助

问题背景

开发搜索按钮功能时,使用如下代码拼接SQL执行查询:

def search(self):
    conn=mysql.connector.connect(host="localhost",username="root",password="krish@123",database="face_monitoring") 
    mycursor=conn.cursor()
    mycursor.execute("select * from room where"+str(self.search_var.get())+" LIKE '%"+str(self.txt_search.get())+"%'")
    rows=mycursor.fetchall()
    if len(rows)!=0:
        self.room_details.delete(*self.room_details.get_children())
        for i in rows:
            self.room_details.insert("",END,values=i)
        conn.commit()
    conn.close()

运行时抛出如下错误:

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Name LIKE '%krishna mishra%'' at line 1

错误原因
  • 触发语法报错的核心问题是SQL拼接遗漏空格:代码里的SQL片段"select * from room where"中,where关键字后没有加空格,和后续动态获取的查询字段名直接粘连。从报错信息可以判断这次选的查询字段是Name,最终拼接出的非法SQL片段为whereName LIKE,不符合SQL语法规则,直接触发1064错误。
  • 代码存在SQL注入安全风险:当前写法直接把用户选择的字段、输入的搜索关键词通过字符串拼接嵌入SQL语句,没有做任何校验和转义,恶意用户可以构造特殊输入实现拖库、删表等非法操作。
  • 存在冗余代码:conn.commit()的作用是提交数据变更事务,仅对INSERT/UPDATE/DELETE这类修改数据的操作生效,SELECT查询场景不需要调用。
修复方案
  • 在SQL语句的where关键字后补空格,保证和后续字段名正常分隔
  • 对动态传入的查询字段增加白名单校验(由于SQL参数化不支持字段、表名这类标识符传参,必须通过白名单限制允许查询的字段,堵上字段层面的注入风险)
  • 搜索关键词部分改用参数化查询传值,不要手动拼接引号和模糊匹配符号,由数据库连接器自动处理转义,彻底解决值层面的SQL注入问题
  • 删除查询场景下冗余的conn.commit()调用

修复后的参考代码:

def search(self):
    # 按照room表实际的字段名配置允许搜索的字段白名单
    ALLOW_SEARCH_FIELDS = {"room_id", "room_name", "Name", "location"}
    search_field = str(self.search_var.get())
    # 传入字段不在白名单内直接拦截,避免非法参数
    if search_field not in ALLOW_SEARCH_FIELDS:
        raise ValueError("不支持的查询字段")
    search_keyword = str(self.txt_search.get())

    conn = mysql.connector.connect(
        host="localhost",
        username="root",
        password="krish@123",
        database="face_monitoring"
    )
    mycursor = conn.cursor()
    # where后补空格,字段名校验后拼接,值部分用%s做占位符
    query_sql = f"SELECT * FROM room WHERE {search_field} LIKE %s"
    # 模糊匹配的通配符和搜索词一起作为参数传入,连接器自动处理转义
    mycursor.execute(query_sql, (f"%{search_keyword}%",))
    rows = mycursor.fetchall()

    if len(rows) != 0:
        self.room_details.delete(*self.room_details.get_children())
        for row in rows:
            self.room_details.insert("", END, values=row)
    
    conn.close()

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:42:27