mysql.connector游标未连接错误(2055):代码首次正常再次执行报错
解决MySQL游标报错:Cursor is not connected
问题原因
你这段代码的问题很明确:每次执行完order()函数都会调用cur.close()关闭游标。第一次运行时游标处于正常连接状态,执行完毕后被直接关掉;第二次再调用cur.execute()时,游标已经是断开状态,自然触发了2055错误。
解决方案
有两种简单的修复方式:
方式一:不要提前关闭游标,或每次查询前重建游标
如果后续还需要复用这个游标,直接把cur.close()这行代码注释掉即可。如果必须管理游标生命周期,可以在每次执行查询前重新创建游标(前提是数据库连接conn保持有效):
def order(): order_options = {1: "Serial_no",2: "Name_of_wildlife",3: "State",4: "No_of_species",5: "Total_area",6: "Total_population"} a = input("\nEnter Favourable Arrangement Order(asc or desc) : ") if a not in ["asc", "desc"]: return order() print("\n========================Chose value to Order By========================") for i in range(1, 7): print(f"\n{i}) Order by {order_options[i]}") Ord = int(input("\nENTER YOUR CHOICE IN NUMBER(1 TO 6) : ")) if Ord not in range(1, 7): print("Please enter Correct Option.") return order() # 全局声明游标,重新创建(确保conn是已建立的数据库连接) global cur cur = conn.cursor() cur.execute(f"SELECT * FROM RECORD ORDER BY {order_options[Ord]} {a}") rec = cur.fetchall() headers = ['Serial_no', 'Name_of_wildlife', 'State', 'No_of_species', 'Total_area', 'Total_population'] print(tabulate.tabulate(rec, headers=headers, tablefmt="grid")) # 注释掉关闭游标的代码,避免后续复用时报错 # cur.close()
方式二:用上下文管理器自动管理游标
使用with语句创建游标,这样代码块执行完毕后会自动关闭游标,且每次调用都会生成新的游标,彻底避免重复使用已关闭游标的问题:
def order(): order_options = {1: "Serial_no",2: "Name_of_wildlife",3: "State",4: "No_of_species",5: "Total_area",6: "Total_population"} a = input("\nEnter Favourable Arrangement Order(asc or desc) : ") if a not in ["asc", "desc"]: return order() print("\n========================Chose value to Order By========================") for i in range(1, 7): print(f"\n{i}) Order by {order_options[i]}") Ord = int(input("\nENTER YOUR CHOICE IN NUMBER(1 TO 6) : ")) if Ord not in range(1, 7): print("Please enter Correct Option.") return order() # 使用with上下文管理器,自动创建、关闭游标 with conn.cursor() as cur: cur.execute(f"SELECT * FROM RECORD ORDER BY {order_options[Ord]} {a}") rec = cur.fetchall() headers = ['Serial_no', 'Name_of_wildlife', 'State', 'No_of_species', 'Total_area', 'Total_population'] print(tabulate.tabulate(rec, headers=headers, tablefmt="grid"))
额外提示
当前的SQL语句存在SQL注入风险,虽然你用order_options做了字段白名单验证,但更规范的做法是避免直接字符串拼接。不过MySQL对ORDER BY的参数化支持有限,你可以保持当前白名单的方式,确保输入的排序字段和方向都是安全的。
内容的提问来源于stack exchange,提问作者Pranav Chauhan
相关产品推荐
相关产品推荐

