如何向SQLite插入含'/'的值?代码报错问题排查
问题原因与解决方案
你碰到的这个syntax error是两个问题叠加导致的:
1. 错误的SQL语句拼接方式
你用字符串拼接+%s格式化生成SQL,会把URL直接裸写入语句中。比如当href是https://www.foo.com/bar.html时,最终生成的SQL是:
INSERT OR IGNORE INTO your_table (url) values (https://www.foo.com/bar.html)
SQLite会把https:当成无效的语法关键字,后面的//直接触发语法错误——合法的SQL字符串必须用单引号包裹,但手动加引号不仅麻烦,遇到URL里的单引号等特殊字符时还是会出错。
2. SQLite不支持%s作为参数占位符
%s是MySQL等数据库常用的占位符,但SQLite的标准参数占位符是?,直接用%s格式化属于用错了语法规则。
正确写法(参数化查询)
这是操作数据库的标准最佳实践,既解决语法问题,又彻底杜绝SQL注入风险:
conn = sqlite3.connect(self.__database_name) c = conn.cursor() # 用?作为参数占位符,表名用f-string拼接(确保表名是可信的内部变量) sql = f'INSERT OR IGNORE INTO {self.__article_url_table_name} (url) VALUES (?)' # 参数放在execute的第二个参数中,必须是元组/列表,单个参数要加逗号 c.execute(sql, (href,)) conn.commit()
关键注意点:
- 参数化查询会由数据库驱动自动处理字符串的引号包裹和特殊字符转义,无需手动操作
execute的第二个参数必须是序列(元组或列表),哪怕只有一个参数也要写成(href,)——少了逗号就不是元组,会触发参数数量不匹配的错误- 如果表名是用户输入的不可信内容,不要用f-string拼接,否则仍存在注入风险(你的表名是类内私有变量,安全性没问题)
内容的提问来源于stack exchange,提问作者Rahul Iyer
相关产品推荐
相关产品推荐

