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

Python查询tbl_timeout触发InternalError问题求助

问题

希望先验证emp_id的有效性,再查询并展示tbl_timeout表中对应员工的记录,但运行Python代码时终端持续抛出如下错误:

raise InternalError("Unread result found")
mysql.connector.errors.InternalError: Unread result found
File "c:\Users\Booster\Documents\python\main.py", line 230, in showtimeout
if con.is_connected():
File "C:\Users\Booster\AppData\Local\Programs\Python\Python310\lib\site-packages\mysql\connector\connection_cext.py", line 322, in is_connected
self.handle_unread_result()

相关代码块:

def showtimeout():
    timerec = tkinter.Tk()
    timerec.title("Time in Records")
    timerec.geometry("600x200")
    try:
        con = mysql.connector.connect(host='localhost', port='3306', database='db_empdb', user='root', password='')
        tree=ttk.Treeview(timerec)
        cursor = con.cursor()

        query = "SELECT emp_id FROM tbl_employee WHERE emp_id = %s"
        cursor.execute(query, (adwin_entry.get(),))
        result = cursor.fetchone()
        if result:
            query = f"SELECT * FROM tbl_timeout WHERE emp_id = {adwin_entry.get()}"
            cursor.execute(query)
            con.commit()
            rows=cursor.fetchall()
            columns = [desc[0] for desc in cursor.description]
            tree["columns"] = columns
            tree.heading("#0", text="Index")
            for col in columns:
                tree.heading(col, text=col)
                tree.column(col, width=100, anchor="center")
            for i, row in enumerate(rows):
                tree.insert("", "end", text=str(i), values=row)
            tree.pack(fill="both", expand=True)
            con.commit()
            cursor.close()
        else:
            messagebox.showerror("Failed", "Employee ID not found!")
            
    except Error as err:
        print("Access Failed! {}".format(err))
    finally:
        if con.is_connected():
            con.close()
            print("Connection Successful!")
问题原因及修复

这个错误核心原因是MySQL Connector/Python的游标在执行新查询前,未完全读取上一次查询的结果集,同时代码还存在其他风险和冗余操作,以下是具体修复方案:

1. 解决未读结果集问题

第一次执行SELECT emp_id后,即便调用了fetchone(),若表中存在重复emp_id,游标仍会残留未读取的结果。复用同一个游标执行新查询时,就会触发"Unread result found"错误。

修复方式:

  • 为不同查询创建独立游标(更推荐,避免结果集冲突);
  • 或在执行新查询前,调用cursor.fetchall()清空所有未读结果。

2. 移除不必要的事务提交

SELECT查询不需要调用con.commit(),该操作仅针对INSERT/UPDATE/DELETE等写操作,多余的提交会造成无效事务开销。

3. 修复SQL注入漏洞

代码中用f-string拼接SQL语句f"SELECT * FROM tbl_timeout WHERE emp_id = {adwin_entry.get()}"存在严重SQL注入风险,必须改用参数化查询,和第一次验证查询的写法保持一致。

修复后的完整代码

def showtimeout():
    timerec = tkinter.Tk()
    timerec.title("Time in Records")
    timerec.geometry("600x200")
    try:
        con = mysql.connector.connect(host='localhost', port='3306', database='db_empdb', user='root', password='')
        tree=ttk.Treeview(timerec)
        
        # 验证emp_id有效性,使用独立游标
        validate_cursor = con.cursor()
        query = "SELECT emp_id FROM tbl_employee WHERE emp_id = %s"
        validate_cursor.execute(query, (adwin_entry.get(),))
        result = validate_cursor.fetchone()
        validate_cursor.close()
        
        if result:
            # 查询超时记录,使用新游标
            query_cursor = con.cursor()
            # 参数化查询,避免SQL注入
            query = "SELECT * FROM tbl_timeout WHERE emp_id = %s"
            query_cursor.execute(query, (adwin_entry.get(),))
            rows = query_cursor.fetchall()
            columns = [desc[0] for desc in query_cursor.description]
            
            tree["columns"] = columns
            tree.heading("#0", text="Index")
            for col in columns:
                tree.heading(col, text=col)
                tree.column(col, width=100, anchor="center")
            for i, row in enumerate(rows):
                tree.insert("", "end", text=str(i), values=row)
            tree.pack(fill="both", expand=True)
            
            query_cursor.close()
        else:
            messagebox.showerror("Failed", "Employee ID not found!")
            
    except Error as err:
        print("Access Failed! {}".format(err))
    finally:
        # 先判断连接对象是否存在,避免未建立连接时触发错误
        if 'con' in locals() and con.is_connected():
            con.close()
            print("Connection closed!")

额外优化点

  • 在finally块中增加con的存在性判断,避免未建立连接时抛出NameError;
  • 拆分游标职责,验证和查询使用独立游标,代码逻辑更清晰;
  • 移除所有SELECT操作后的无效commit()调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:57:39