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

Python SQLite可选多WHERE条件查询的动态参数拼接问题求解

SQLite动态多条件零件检索的实现方案

核心思路是同步维护条件片段列表、参数值列表,每追加一个筛选条件,就同步往参数列表加对应的值,最终根据两个列表动态拼接SQL、生成参数元组,从根源解决占位符不匹配、SQL注入问题,同时天然兼容无筛选条件查全表的场景。

具体实现步骤

  • 初始化两个空列表:where_clauses 存储合法的WHERE条件片段,params 存储与占位符一一对应的参数值
  • 逐个校验文本类输入项:过滤前后空格后非空的,才把对应条件片段加入where_clauses,处理后的参数值加入params
  • 安全处理作业类型筛选:所有可选作业类型为代码硬编码的固定枚举值,仅根据复选框勾选状态,把固定合法值加入参数列表,禁止把用户可控的任意字符串直接拼接进SQL
  • 拼接最终SQL:如果where_clauses为空,直接执行全表查询;非空则用AND连接所有条件片段,拼接WHERE子句,把params转为元组传入execute方法即可

可直接复用的代码示例

假设你的PySimpleGUI控件key与表结构如下:

  • 文本输入key:-PART_NAME-(零件名称)、-PART_SERIES-(零件系列)、-PART_NUM-(零件编号)、-PART_SIZE-(零件尺寸)
  • 复选框key:-FIT_CHECK-(Fit作业)、-WELD_CHECK-(Weld作业)、-ASSEMBLE_CHECK-(Assemble作业)
  • 数据表名为parts,作业类型存储在job_type字段中
import sqlite3

def part_search(gui_values):
    where_clauses = []
    params = []

    # 处理文本类筛选条件
    # 零件名称:模糊匹配
    part_name = gui_values.get('-PART_NAME-', '').strip()
    if part_name:
        where_clauses.append("part_name LIKE ?")
        params.append(f"%{part_name}%")
    
    # 零件系列:模糊匹配
    part_series = gui_values.get('-PART_SERIES-', '').strip()
    if part_series:
        where_clauses.append("part_series LIKE ?")
        params.append(f"%{part_series}%")
    
    # 零件编号:精确匹配,需要模糊可自行改为LIKE
    part_number = gui_values.get('-PART_NUM-', '').strip()
    if part_number:
        where_clauses.append("part_number = ?")
        params.append(part_number)
    
    # 零件尺寸:模糊匹配
    part_size = gui_values.get('-PART_SIZE-', '').strip()
    if part_size:
        where_clauses.append("part_size LIKE ?")
        params.append(f"%{part_size}%")

    # 处理作业类型复选框:完全规避SQL注入
    # 硬编码所有合法作业类型映射,不直接使用用户传入的字符串拼接SQL
    job_type_config = [
        ('-FIT_CHECK-', 'Fit'),
        ('-WELD_CHECK-', 'Weld'),
        ('-ASSEMBLE_CHECK-', 'Assemble')
    ]
    selected_jobs = [type_val for widget_key, type_val in job_type_config if gui_values.get(widget_key, False)]
    if selected_jobs:
        # 生成与选中数量匹配的占位符
        placeholder_str = ', '.join(['?'] * len(selected_jobs))
        where_clauses.append(f"job_type IN ({placeholder_str})")
        params.extend(selected_jobs)

    # 拼接最终SQL
    base_query = "SELECT * FROM parts"
    if where_clauses:
        final_query = f"{base_query} WHERE {' AND '.join(where_clauses)}"
    else:
        final_query = base_query

    # 执行查询,参数顺序、数量与占位符完全匹配
    conn = sqlite3.connect('parts.db')
    cursor = conn.cursor()
    cursor.execute(final_query, tuple(params))
    search_result = cursor.fetchall()
    conn.close()

    return search_result

适配说明

  • 如果你的表结构是用三个独立布尔字段存储作业适配情况(比如is_fit/is_weld/is_assemble三个值为0/1的字段),只需要把作业类型处理部分的逻辑改为:勾选对应复选框时,向where_clauses加入is_fit = ?这类固定片段,同时向params加入1即可,核心的双列表同步逻辑不变
  • 所有用户可修改的输入值全部通过?占位符传入,不会存在SQL注入风险
  • 无任何有效筛选条件时,where_clauses为空,直接返回全表数据,不需要额外写特殊分支处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:51:29