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

Python可复用SQLite查询函数报错:误将输入值识别为列名

问题根源与解决方案

问题原因

你直接把用户输入值拼接到SQL语句里,当输入是字符串时,生成的SQL没给值加引号,导致SQL引擎把输入值当成了列名。比如输入Math,生成的SQL是:

SELECT subject_name FROM subject where subject_name = Math;

这里Math没有引号,SQL会认定它是列名而非字符串值,因此抛出“无此列”的错误。同时这种拼接方式存在SQL注入风险,安全性极低。

解决方案:改用参数化查询

SQLite支持参数化查询,用占位符?代替直接拼接值,让数据库引擎自动处理值的转义和引号,彻底解决这个问题。

1. 重构retrieve_data函数

修改函数,新增params参数传递条件的参数值,避免直接拼接字符串:

import sqlite3

def retrieve_data(self, table_name, columns="*", condition="", params=None):
    try:
        # 确保params是列表/元组,避免空值报错
        params = params or ()
        # 构造SELECT语句
        select_query = f"SELECT {columns} FROM {table_name}"
        if condition:
            select_query += f" {condition}"
        select_query += ";"

        # 执行参数化查询
        self.cursor.execute(select_query, params)

        # 获取所有结果
        result = self.cursor.fetchall()
        return result

    except sqlite3.Error as e:
        print(f"Error retrieving data: {e}")
        return None

注意:函数里的cursor应该是类实例的属性(比如self.cursor),如果之前用的是全局cursor,建议改为实例属性,保证线程安全和复用性。

2. 修改调用代码

调用时用占位符?代替条件里的具体值,把实际值传入params参数:

def add_subject(self, event):
    subject_name = self.subject_name_text.GetValue().strip()
    if subject_name:
        # 参数化查询:占位符?对应params里的subject_name
        get_subject_list = SchoolManagementSystem.retrieve_data(
            SchoolManagementSystem, 
            "subject", 
            "subject_name", 
            "WHERE subject_name = ?", 
            (subject_name,)
        )

        # 将查询结果转为字符串列表(fetchall返回的是元组列表)
        subject_list = [item[0] for item in get_subject_list] if get_subject_list else []
        
        if subject_name in subject_list:
            print(f"Subject {subject_name} already exists.")
        else:
            # 直接执行插入,无需手动维护subject_list(数据库是唯一数据源)
            SchoolManagementSystem.insert_row(
                SchoolManagementSystem, 
                "subject", 
                {"subject_name": subject_name}
            )
            print(f"Subject {subject_name} added successfully.")

额外优化:

  • 对用户输入做了strip()处理,避免空字符串或前后空格引发的错误
  • 直接从数据库获取最新数据,无需手动维护subject_list,保证数据一致性
  • 修正了原代码中Class的拼写错误(应为Subject)

额外注意事项

  • 永远不要直接将用户输入拼接到SQL语句中,参数化查询是防止SQL注入和格式错误的标准做法
  • 如果需要支持多条件查询,只需扩展condition字符串和params参数即可,示例:
    # 多条件查询示例
    get_subject_list = SchoolManagementSystem.retrieve_data(
        self,
        "subject",
        "*",
        "WHERE subject_name = ? AND grade = ?",
        (subject_name, 10)
    )
    

内容的提问来源于stack exchange,提问作者Z.Edibo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:17:26