Python sqlite3用f-string传时间变量查询报near语法错误
错误原因
f-string拼接时直接把max_tyme的字符串值插入了SQL,没有给时间值包裹SQL要求的单引号,最终执行的SQL片段变成了AND tyme > 2022-06-22 17:14:01.048,解析器读到空格后的17无法识别语法,直接报错。你硬编码能运行的本质是手动给时间值加了单引号,符合SQL字符串值的书写规范,和时间格式本身没有关系。
注意:直接用字符串拼接生成SQL存在严重SQL注入风险,所有数据库交互场景都不推荐这种写法。
推荐解决方案:使用参数化查询
Python的sqlite3模块原生支持参数化传参,用?作为占位符,不需要手动处理引号、特殊字符转义,从根源避免语法错误和注入风险,代码如下:
con = sqlite3.connect('tables.db') cur = con.cursor() max_tyme = '2022-06-22 17:14:01.048' # 变量位置用?占位,所有参数按顺序放在元组中,作为execute的第二个参数传入 cur.execute('''SELECT A.ID, B, A, tyme FROM A, BD WHERE A.ID = BD.ID AND tyme > ?''', (max_tyme,)) # 后续获取结果、提交事务等操作正常写即可 result = cur.fetchall() con.close()
不推荐的临时方案(仅做原理说明)
如果一定要用f-string拼接,需要在变量替换的位置手动补外层的单引号,和你硬编码的格式完全对齐:
# 存在SQL注入、特殊字符转义失败风险,非特殊场景不要用 cur.execute(f'''SELECT A.ID, B, A, tyme FROM A, BD WHERE A.ID = BD.ID AND tyme > '{max_tyme}' ''')
这种写法只要变量内容里包含单引号,就会再次触发语法错误,完全无法抵御SQL注入攻击,仅用来帮你理解之前报错的逻辑。
内容的提问来源于stack exchange,提问作者Vav1r
相关产品推荐
相关产品推荐

