SQL语句在SQLite Browser正常却在Qt5.11.2执行报错的解决办法
解决Qt 5.11.2中执行含窗口函数的SQLite语句失败的问题
我一眼就看出问题所在了——Qt 5.11.2自带的SQLite版本不支持你用到的窗口函数ROW_NUMBER() OVER()。
为什么会出现这种矛盾?
SQLite Browser通常会使用较新的SQLite版本(SQLite 3.25.0及以后才正式支持窗口函数特性),但Qt 5.11.2默认捆绑的SQLite版本是3.20.1,这个版本还没有实现窗口函数。所以你在SQLite Browser里能正常运行的语句,到Qt环境里就会触发语法错误。
你可以先验证当前Qt项目使用的SQLite版本,加一行代码打印确认:
qDebug() << "当前SQLite版本:" << QSqlDatabase::database().driver()->version();
输出结果大概率是低于3.25.0的数值。
三种解决办法,按需选择
1. 升级Qt版本(最省心的方案)
直接把Qt升级到5.12或更高版本——Qt 5.12开始捆绑的SQLite版本已经更新到支持窗口函数的版本了。升级后不需要修改任何代码,你的原SQL语句就能正常执行。
2. 替换项目中的SQLite库(适合无法升级Qt的场景)
如果没法升级Qt,你可以自己编译最新版的SQLite静态库,让Qt链接这个新版本而非自带的旧版本:
- 从SQLite官方渠道下载最新源码包
- 将源码编译成静态库(比如
libsqlite3.a或sqlite3.lib) - 在Qt项目的
.pro文件中添加配置,指定链接新库并禁用Qt自带的SQLite:
记得把LIBS += -L/path/to/your/sqlite/lib -lsqlite3 DEFINES += SQLITE_DISABLE_LFS QT_NO_SQLITE/path/to/your/sqlite/lib替换成你实际的库文件路径。
3. 改写SQL语句,避开窗口函数(无需修改运行环境)
如果上面两种方法都没法实施,你可以把原查询改写成不依赖窗口函数的写法,同样能实现“获取每个FaceID最新的一条记录,再取前5条”的需求:
SELECT r.ID, r.FaceID, r.Image FROM ( -- 先找出每个FaceID对应的最新时间 SELECT FaceID, MAX(DATE || ' ' || TIME) AS latest_datetime FROM ( SELECT FaceID, DATE, TIME FROM recorded_face_whitelist_log UNION ALL SELECT FaceID, DATE, TIME FROM recorded_face_log ) AS combined_logs GROUP BY FaceID ) AS latest_info -- 关联回原表拿到对应记录 JOIN ( SELECT ID, FaceID, Image, DATE, TIME FROM recorded_face_whitelist_log UNION ALL SELECT ID, FaceID, Image, DATE, TIME FROM recorded_face_log ) AS r ON r.FaceID = latest_info.FaceID AND r.DATE || ' ' || r.TIME = latest_info.latest_datetime ORDER BY r.DATE DESC, r.TIME DESC LIMIT 5;
注意:这个写法依赖DATE和TIME的格式是可拼接后比较大小的(比如YYYY-MM-DD和HH:MM:SS),如果你的时间格式不同,需要调整拼接或比较的逻辑。
内容的提问来源于stack exchange,提问作者StereoMatching
相关产品推荐
相关产品推荐

