Python借助psycopg2执行带LIKE的pharmacy表查询报语法错误
代码存在的核心问题
- 触发语法报错的直接原因:字符串字面量未按SQL规则加单引号包裹。你代码拼接生成的最终执行SQL为
select * from pharmacy where ref_no LIKE 123%,LIKE关键字后面的匹配内容属于字符串类型,PostgreSQL语法要求这类字面量必须用单引号包裹成'123%'的形式。你漏加了引号,数据库会把123识别为数值字面量,后面直接跟%通配符没有语法边界,最终触发输入末尾位置的语法错误。 - 潜在隐患:直接拼接SQL存在注入风险。这种把所有用户输入直接拼进SQL字符串的写法,除了容易出现刚才的引号漏加、转义不充分的语法问题,还会被恶意输入构造出破坏性的查询逻辑,影响数据安全。
正确修复方案
不要手动拼接SQL语句的字符串结构,结合psycopg2自带的参数化查询能力调整写法:
- 对查询用到的列名做白名单校验:列名属于数据库结构标识符,无法通过参数占位符传递,必须提前定义业务内允许搜索的列范围(比如只开放
ref_no、drug_name这类确定的字段),把输入框传来的列名和白名单比对,不匹配的直接拦截,从根源避免列名注入。 - 对所有实际查询值(包括LIKE的匹配内容)走psycopg2的参数化传递,由数据库驱动自动完成字符串的引号包裹、特殊字符转义,不要手动把通配符拼到SQL字符串结构里。
示例正确代码:
# 预先定义允许搜索的列白名单 ALLOWED_SEARCH_COLUMNS = {"ref_no", "drug_name", "spec", "production_date"} search_col = self.search_var.get() # 列名合法性校验 if search_col not in ALLOWED_SEARCH_COLUMNS: raise ValueError("非法的查询字段") # 把通配符拼到参数值内部,不嵌入SQL语句结构 like_pattern = f"{self.searchtxt_var.get()}%" # 使用psycopg2的%s占位符做参数化查询,参数以元组形式传入 cursor.execute( f"select * from pharmacy where {search_col} LIKE %s", (like_pattern,) )
修复后的效果
- 列名经过白名单校验后再嵌入SQL结构,不存在注入风险
- 实际匹配值
like_pattern完全由驱动做转义处理,自动给字符串加上合法的单引号,不会出现漏加引号的语法问题,也能避免输入内容带单引号这类特殊字符导致的查询崩溃。
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

