使用查询参数实现SQLite日期区间搜索的参数化查询问题
解决SQLite参数化查询日期区间的问题
你当前的问题出在没有使用SQLite官方推荐的参数化查询方式,而是用了字符串格式化拼接SQL语句,这不仅容易引发SQL注入风险,还会导致日期参数的格式处理错误。
错误原因分析
你写的这行代码:
cursor.execute("SELECT * FROM tz WHERE UL_Time BETWEEN '%s' AND '%s'" % (startdate, enddate))
会把startdate和enddate直接拼接到SQL字符串中,最终生成的SQL语句是:
SELECT * FROM tz WHERE UL_Time BETWEEN '2022-11-05' AND '2022-11-25'
如果UL_Time字段是日期类型,SQLite可能无法正确解析带单引号的字符串;另外你提到的硬编码语句BETWEEN 2022-11-01 AND 2022-11-25其实是错误写法——这里的2022-11-01会被SQLite解析为数值运算(2022-11-1=2010),能运行只是巧合,并非正确的日期查询方式。
正确的参数化查询写法
SQLite的参数化查询使用?作为占位符,不需要手动给参数加单引号,sqlite3模块会自动处理类型转换和转义:
cursor.execute("SELECT * FROM tz WHERE UL_Time BETWEEN ? AND ?", (startdate, enddate))
把参数放在execute方法的第二个参数(元组形式)中,这才是官方推荐的安全且正确的参数传递方式。
修改后的完整代码
import sqlite3 def readSqliteTable(): try: sqliteConnection = sqlite3.connect('testDB.sqlite') cursor = sqliteConnection.cursor() print("Connected to SQLite") startdate = "2022-11-05" enddate = "2022-11-25" print("startdate =", startdate, "enddate =", enddate) # 使用参数化查询的正确写法 cursor.execute("SELECT * FROM tz WHERE UL_Time BETWEEN ? AND ?", (startdate, enddate)) records = cursor.fetchall() print("Total rows are: ", len(records)) print("Printing each row") for row in records: print("Id: ", row[0]) print("Updated: ", row[1]) print("Title: ", row[2]) print("UL_Time: ", row[3]) print("Size: ", row[4]) print("\n") cursor.close() except sqlite3.Error as error: print("Failed to read data from sqlite table", error) finally: if sqliteConnection: sqliteConnection.close() print("The SQLite connection is closed")
额外说明
- 参数化查询不仅能解决日期格式问题,还能有效防止SQL注入攻击;
- 如果
UL_Time字段存储的是字符串类型,确保日期格式(YYYY-MM-DD)和数据库中的一致即可;如果是DATE/DATETIME类型,sqlite3会自动处理字符串到日期类型的转换。
内容的提问来源于stack exchange,提问作者Cyberlauncher
相关产品推荐
相关产品推荐

