You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QSqlQuery的last方法失效:无法获取SQLite查询结果集大小

解决QSqlQuery::last()返回false无法获取结果集大小的问题

我之前也碰到过一模一样的问题,Qt对SQLite的QSqlQuery默认采用**forward-only(仅向前)**的查询模式,这种模式下last()、size()这类需要随机访问结果集的方法都会失效——因为结果集是流式返回的,并没有被完整加载到内存里,自然没法直接跳到最后一行。

下面给你两种可行的解决方案,你可以根据自己的场景选择:

方案一:修改查询模式,允许随机访问

如果你确实需要遍历结果集同时获取总行数,可以先把查询设置为非仅向前模式,让Qt把整个结果集缓存到内存里,之后就能正常调用last()了:

int entries() { 
    // 建议复用已创建的连接,而非每次调用都新建
    QSqlDatabase db = QSqlDatabase::database("SELECT_CON"); 
    if (!db.isOpen()) {
        db.open();
    }
    QSqlQuery q(db);
    q.setForwardOnly(false); // 关键:关闭仅向前模式
    if (q.exec("SELECT * FROM Test;")) {
        if (q.last()) { // 现在应该能成功跳到最后一行
            int rowCount = q.at() + 1; // at()返回从0开始的行索引,行数需要+1
            q.first(); // 如果之后还要遍历结果集,记得跳回第一行
            return rowCount;
        } else {
            // 结果集为空,返回0
            return 0;
        }
    } else {
        // 查询执行失败,打印错误信息
        qDebug() << "Query failed:" << q.lastError().text();
        return -1;
    }
}

⚠️ 注意:这种方式会把整个结果集加载到内存,如果你的表数据量很大,可能会占用较多内存,要谨慎使用。

方案二:用SQL COUNT()直接统计行数(更高效)

如果只是想获取表的条目数,完全没必要加载整个结果集,直接用SQL的COUNT(*)查询是最优解:

int entries() { 
    QSqlDatabase db = QSqlDatabase::database("SELECT_CON");
    if (!db.isOpen()) {
        db.open();
    }
    QSqlQuery q(db);
    if (q.exec("SELECT COUNT(*) FROM Test;")) {
        if (q.next()) { // 结果集只有一行,直接读取第一行数据
            return q.value(0).toInt();
        }
    } else {
        qDebug() << "Query failed:" << q.lastError().text();
        return -1;
    }
    return 0;
}

这种方式只返回一个统计数值,性能比加载整个结果集好太多,推荐优先使用。

另外提个小细节:你现在的代码里每次调用entries()都用addDatabase创建新连接,其实可以用QSqlDatabase::database("SELECT_CON")复用已有的连接,避免创建过多数据库连接带来的额外开销。

内容的提问来源于stack exchange,提问作者Sailordi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:03:32