Python操作SQLite3校验用户名PIN时username、pin未识别报错解决
报错原因
- 变量作用域问题:
read_from_db()函数内使用的username、pin没有被定义。这两个值既没有作为函数参数传入,也没有在函数内部赋值,也没有声明引用全局变量,VSCode静态检查时找不到对应标识符,就会标注未定义波浪线,代码运行时也会直接抛出NameError。 - 游标结果读取逻辑错误:你在函数外已经执行过一次
results = cursor.fetchall(),SQLite的游标是单次消费的,所有查询结果已经在这一步被取完,后续再调用cursor.fetchall()只会返回空列表,函数内的循环根本拿不到任何数据。 - 原有校验逻辑存在漏洞:逐行遍历判断值是否在row中的写法既低效,也容易出现误判,比如逐行匹配时每遇到一行不匹配的数据就会打印一次"Invalid Pin",不符合一次校验只返回一次结果的预期。
修复方法
- 给校验函数增加入参,用来接收用户输入的用户名和PIN,解决变量未定义问题。
- 改用参数化查询直接匹配数据库中符合用户名+PIN的记录,不需要遍历全表,同时避免游标提前被消费的问题,还能防范SQL注入风险。
- 调整返回逻辑:查询到匹配记录就提示成功,查询不到就提示无效,避免重复打印错误信息。
- 插入预置数据时增加
OR IGNORE判断,避免重复运行代码时因为PIN是主键触发重复插入报错,操作完成后记得提交事务、关闭数据库连接。
修复后可运行代码
import sqlite3 # PHASE 2 (带数据库版本) SQLite 3 # 定义数据库连接和游标 connection = sqlite3.connect('Bank_Users.db') cursor = connection.cursor() # 创建银行用户表 command1 = """ CREATE TABLE IF NOT EXISTS bank(pin INTEGER PRIMARY KEY , username text )""" cursor.execute(command1) # 预置用户数据(加OR IGNORE避免重复运行触发主键冲突) user_list = [ (7620, 'Kailas Kurup'), (4638, 'Bethany Watkins'), (3482, 'John Hammond'), (3493, 'Melissa Rodriguez'), (9891, 'Kevin Le') ] cursor.executemany("INSERT OR IGNORE INTO bank VALUES (?, ?)", user_list) connection.commit() # 数据库用户信息校验函数 def read_from_db(input_username, input_pin): # 用参数化查询做精准匹配,无需遍历全表 cursor.execute("SELECT username, pin FROM bank WHERE pin = ? AND username = ?", (input_pin, input_username)) match_result = cursor.fetchone() if match_result: print("Success") return True else: print("Invalid Pin") return False # 示例调用:接收用户输入完成校验 if __name__ == "__main__": input_pin = int(input("请输入您的PIN:")) input_username = input("请输入您的用户名:") read_from_db(input_username, input_pin) # 操作完成关闭游标和连接 cursor.close() connection.close()
内容的提问来源于stack exchange,提问作者kkurup
相关产品推荐
相关产品推荐

