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

Python程序按姓名查询SQL数据库无结果输出的问题排查求助

问题诊断与修复方案

嘿,我帮你找到了按姓名查询时程序直接终止的核心原因,还有对应的修复方案:

1. 最直接的崩溃元凶:SQL语法错误(字符串拼接坑)

你现在用字符串拼接的方式构建姓名查询的SQL语句,这会导致两个问题:

  • 如果用户输入的姓名包含单引号(比如O'Conner),拼接后的SQL会出现语法错误,数据库执行失败,而你的代码没捕获这个异常,程序直接崩了。比如输入O'Neil,拼接后的SQL会变成:
    SELECT ... WHERE C.Fname = '' AND C.Lname = 'O'Neil'
    
    这里的单引号把语句提前闭合,剩下的Neil'完全是无效语法,数据库直接报错,程序就终止了。
  • 这种写法还存在SQL注入风险,属于不安全的编码方式。

2. 缺少异常兜底逻辑

和按ID查询的代码不同,姓名查询的部分没有try-except块,任何执行错误(比如上面的语法错、数据库临时断开)都会直接终止程序,连错误提示都没有。

3. 可选优化:空白输入的逻辑不符合预期

你允许用户按回车留空名字,但当前的SQL会查询Fname = ''的用户,这显然不是“留空表示不限制该条件”的本意吧?


修复后的完整代码

下面是修复了所有问题的代码,同时保留了你原来的功能逻辑:

while True: # 循环验证用户输入合法性
    ui = input("Would you like to lookup the customer by Customer ID (1) or Name (2)? >")
    try:
        ui = int(ui)
        if ui in (1, 2):
            break
        else:
            print("Please enter either 1 or 2 to make a selection.")
    except ValueError: # 精准捕获字符串转整数的错误,不用裸except
        print("Invalid selection. Please enter a number.")

if ui == 1:
    while True:
        cid = input("What is the Customer ID? >")
        try:
            cid = int(cid)
            # 这里也改成参数化查询,避免潜在风险
            query = """
                SELECT C.CustID, C.Fname, C.Lname, C.Gender, C.CustState, U.Population 
                FROM Customer C 
                INNER JOIN USState U ON C.CustState = U.StateID 
                WHERE C.CustID = %s
            """
            cursor.execute(query, (cid,)) # 参数化传入值,避免拼接问题
            results = cursor.fetchall()
            if not results:
                print("No customer found with this ID.")
            for x in results:
                print("Customer ID: %d, First Name: %s, Last Name: %s, Gender: %s, State: %s, State Population: %d." 
                      % (x[0], x[1], x[2], x[3], x[4], x[5]))
            break
        except ValueError:
            print("Please enter an integer for Customer ID.")
        except Exception as e: # 捕获数据库相关错误,给出提示
            print(f"Error querying database: {str(e)}")
elif ui == 2:
    while True:
        try:
            fname = input("What is the customer's first name? (press enter for blank) >").strip()
            lname = input("What is the customer's last name? (press enter for blank) >").strip()
            
            # 动态构建查询条件,处理空白输入
            conditions = []
            params = []
            if fname:
                conditions.append("C.Fname = %s")
                params.append(fname)
            if lname:
                conditions.append("C.Lname = %s")
                params.append(lname)
            
            if not conditions:
                print("Please enter at least first name or last name.")
                continue
            
            query = f"""
                SELECT C.CustID, C.Fname, C.Lname, C.Gender, C.CustState, U.Population 
                FROM Customer C 
                INNER JOIN USState U ON C.CustState = U.StateID 
                WHERE {' AND '.join(conditions)}
            """
            cursor.execute(query, params) # 参数化查询,彻底解决语法错误和注入风险
            results = cursor.fetchall()
            
            if not results:
                print("No customers found matching the entered name(s).")
            for x in results:
                print("Customer ID: %d, First Name: %s, Last Name: %s, Gender: %s, State: %s, State Population: %d." 
                      % (x[0], x[1], x[2], x[3], x[4], x[5]))
            break
        except Exception as e:
            print(f"Error querying database: {str(e)}")

关键修复点说明

  • 参数化查询:所有SQL都用cursor.execute(query, params)的方式,把查询值作为参数传入,彻底避免了字符串拼接带来的语法错误和SQL注入风险,这是数据库操作的最佳实践。
  • 精准异常捕获:用ValueError处理输入转整数的错误,用Exception捕获数据库相关错误,出错时会给出明确提示,不会直接终止程序。
  • 空白输入处理:动态构建WHERE条件,如果用户留空姓名,就不会加入该条件,符合“留空表示不限制”的预期,还加了“至少输入一个姓名”的验证。
  • 空结果提示:当没有查询到匹配结果时,会明确告知用户,而不是什么都不输出,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:22:29