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

Python sqlite3更新数据库表时字符串字段更新失败求助

解决SQLite3更新字符串字段的问题

嘿,我来帮你搞定这个SQLite3的更新问题!你遇到的报错 sqlite3.OperationalError: no such column: Adventure 其实原因很明确——字符串类型的值没有被正确包裹在引号里,而且你当前的SQL拼接方式还存在严重的SQL注入风险,咱们一步步来改。

问题根源分析

你现在是直接把用户输入的内容拼接到SQL语句里:

  • 当更新数字字段时,比如输入9.99,拼接后的SQL是SET price=9.99 WHERE game='xxx',数字不需要引号,SQL能正确识别,所以运行正常。
  • 但更新字符串时,比如输入Adventure,拼接后的SQL就变成了SET genre=Adventure WHERE game='xxx',SQL会把Adventure当成一个列名去查找,自然就报错“找不到这个列”了。

而且这种直接拼接用户输入的写法非常危险,万一有人输入恶意内容,会直接篡改你的数据库(也就是SQL注入攻击)。

正确解决方案:使用参数化查询

这是操作数据库的最佳实践,既解决了字符串引号的问题,又能彻底避免SQL注入。修改后的代码如下:

import sqlite3  # 别忘了导入模块哦

def amendRec():
    edit = "yes"
    while edit != 'exit':
        keyfield = input("enter the game name of the record you want to edit. ")
        field = input("enter the field you want to change. ")
        newVal = input("enter the new data for this field. ")
        
        # 用?作为值的占位符,参数放在元组里传递给execute
        # 注意:字段名不能用参数化,建议加个列名白名单校验更安全
        try:
            # 用format处理字段名,值用参数化占位符
            cursor.execute(
                "UPDATE tblGames SET {} = ? WHERE game = ?".format(field),
                (newVal, keyfield)
            )
            conn.commit()
            print("\nRecord Updated\n")
        except sqlite3.OperationalError as e:
            print(f"Error updating record: {e}\n可能是输入的游戏名或字段名无效哦。")
        edit = input("type 'exit' to stop editing, or press enter to continue. \n")
    showtable()

代码要点说明

  1. 参数化占位符?:SQLite3会自动处理不同类型值的格式——字符串会自动加上引号,数字保持原样,彻底解决你之前的类型适配问题。
  2. 字段名处理:字段名不能用参数化,所以如果是用户输入的字段名,最好提前做个白名单校验(比如检查是否在['game', 'genre', 'price']这类合法列名列表里),防止恶意输入。
  3. 恢复异常捕获:把try-except加回来,能友好提示用户错误原因,而不是直接崩溃。

额外提示

之前你手动给keyfield加引号的方式也不安全,用参数化查询后就完全不需要自己处理引号了,数据库驱动会帮你做好所有格式适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:58:50