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

执行view_accounts()函数时触发mysql.connector.errors.InternalError: Unread result found错误的技术求助

Fixing "mysql.connector.errors.InternalError: Unread result found" in Your Code

Let's break down why you're hitting this error and how to fix it, plus a critical security improvement you should make right away.

Why the Error Happens

The "Unread result found" error pops up because you're reusing a single global database connection across multiple functions, and the login() function leaves an unprocessed result set hanging around.

In login(), you run a SELECT query, call fetchone(), but don't fully consume the entire result set or properly close the cursor before moving on to use the same connection in view_accounts(). MySQL Connector keeps track of unread results on a connection, and it blocks new queries until those results are handled.

Fix 1: Properly Handle Cursors & Results

You have two solid options here:

  • Close the cursor after use in every function to clean up the result set
  • Use parameterized queries with buffered cursors (which also solves another big problem we'll talk about)

Fix 2: Eliminate SQL Injection Risks

Right now, you're using f-strings to build SQL queries, which is a huge security hole—attackers can easily inject malicious SQL to steal or delete your data. Always use parameterized queries instead, where MySQL handles escaping input safely.

Modified Working Code

Here's your code with both fixes applied:

import mysql.connector as mysql 

def get_db_connection():
    # Create a new connection per operation (simpler to avoid cursor conflicts)
    return mysql.connect(host="localhost", user="root", password="", database="db_iptech2") 

def login(username, password): 
    conn = get_db_connection()
    # Use parameterized query - %s are safe placeholders
    sql = "SELECT * FROM tbl_account WHERE username = %s AND password = %s" 
    mycursor = conn.cursor() 
    mycursor.execute(sql, (username, password))  # Pass parameters as a tuple
    result = mycursor.fetchone() 
    row_count = 1 if result else 0  # Check directly for a match instead of using rowcount
    mycursor.close()
    conn.close()
    return row_count 

def register(user, pw, fname, mname, lname): 
    conn = get_db_connection()
    sql = "INSERT INTO tbl_account(username, password, FirstName, MiddleName, LastName) VALUES (%s, %s, %s, %s, %s)" 
    mycursor = conn.cursor() 
    # Pass input values safely to avoid injection
    mycursor.execute(sql, (user, pw, fname, mname, lname)) 
    conn.commit() 
    print("Successfully Registered!") 
    mycursor.close()
    conn.close() 

def view_accounts(): 
    conn = get_db_connection()
    sql2 = "SELECT * FROM tbl_account" 
    mycursor = conn.cursor() 
    mycursor.execute(sql2) 
    for row in mycursor: 
        print(row) 
    mycursor.close()
    conn.close() 

print("(L) Login / (R) Register") 
question = input("Execute: ") 
if question == 'L': 
    user = input("Enter username: ") 
    password = input("Enter Password: ") 
    x = login(user, password) 
    if x > 0: 
        print("Welcome to System") 
        view_accounts() 
    else: 
        print("Incorrect username or Password") 
elif question == 'R': 
    user = input("Enter username: ") 
    password = input("Enter password: ") 
    fname = input("Enter First Name: ") 
    mname = input("Enter Middle Name: ") 
    lname = input("Enter Last Name: ") 
    register(user, password, fname, mname, lname)

Key Changes Explained

  1. Per-function database connections: Instead of a global connection, we create a new connection in each function and close it when done. This avoids conflicts between cursors and unread results entirely.
  2. Parameterized queries: Replaced f-string SQL building with %s placeholders, passing input values as a tuple to execute(). This stops SQL injection cold.
  3. Clean cursor/connection handling: Every cursor and connection is closed after use to free up resources and prevent leftover result sets.

Alternative: Reusing a Single Connection

If you want to keep a single global connection (for performance in larger apps), modify the login() function to either:

  • Close the cursor immediately after fetching the result:
    def login(username, password): 
        sql = "SELECT * FROM tbl_account WHERE username = %s AND password = %s" 
        mycursor = conn.cursor() 
        mycursor.execute(sql, (username, password))
        result = mycursor.fetchone() 
        row_count = 1 if result else 0
        mycursor.close()  # Critical: cleans up the result set
        return row_count 
    
  • Or use a buffered cursor to load all results into memory:
    mycursor = conn.cursor(buffered=True)
    

Either way, never use f-strings for SQL queries—always stick to parameterized inputs.

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

火山引擎 最新活动