首页 文章

SQLite和QSqlQuery - execBatch()的多次调用失败

提问于
浏览
2

我有一个需要重复执行批量插入的类 . QSqlQuery实例是该类的成员 . 起初我尝试了这段代码:

TOMCache::TOMCache(QObject *parent): QObject(parent) {    
    m_setWithGeoQuery.prepare("INSERT OR REPLACE INTO cache_storage(key, value, lat, lng, expiration) VALUES(?, ?, ?, ?, ?)");
}

void TOMCache::flushBuffer() {
    QSqlQuery &query = m_setWithGeoQuery;
    query.addBindValue(m_buffer.at(0));
    query.addBindValue(m_buffer.at(1));
    query.addBindValue(m_buffer.at(2));
    query.addBindValue(m_buffer.at(3));
    query.addBindValue(m_buffer.at(4));
    if(!query.execBatch())
        qWarning() << "-- execBatch() failed: " << query.lastError().text();
    m_buffer.clear();
    m_buffer << QVariantList() << QVariantList() << QVariantList() << QVariantList() << QVariantList();
}

那没用 . 创建的SQLite文件有65536字节,但表cache_storage中只有1行(flushBuffer()被多次调用) . 看起来execBatch()的第一次调用成功执行,下一次调用默认失败(它们一直返回true) . 我意识到以下代码有效:

void TOMCache::flushBuffer() {

    QSqlQuery query;
    query.prepare("INSERT OR REPLACE INTO cache_storage(key, value, lat, lng, expiration) VALUES(?, ?, ?, ?, ?)");
    query.addBindValue(m_buffer.at(0));
    query.addBindValue(m_buffer.at(1));
    query.addBindValue(m_buffer.at(2));
    query.addBindValue(m_buffer.at(3));
    query.addBindValue(m_buffer.at(4));
    if(!query.execBatch())
        qWarning() << "-- execBatch() failed: " << query.lastError().text();
    m_buffer.clear();
    m_buffer << QVariantList() << QVariantList() << QVariantList() << QVariantList() << QVariantList();
}

我有一些问题:

  • 每次调用execBatch()时是否需要创建和销毁QSqlQuery?

  • 如果是这样,为什么execBatch()的后续调用假装成功执行?

  • 第一种情况下的大文件大小怎么样? (只有2个表,另一个是空的)

我应该提一下,这是在BlackBerry 10 OS上运行的应用程序的一部分 . 为了避免每次都创建和销毁QSqlQuery,我还尝试在flushBuffer()的末尾调用query.clear()但是这似乎也从QSqlQuery实例中删除了准备好的SQL(下次调用execBatch()失败) .

编辑:我试图避免每次解析SQL,所以我试图保持m_setWithGeoQuery不被修改,只是在flushBuffer()中复制它:

QSqlQuery query(m_setWithGeoQuery);
    query.addBindValue(m_buffer.at(0));
    ...

令人惊讶的是,它不起作用 . 它的行为与第一个代码段相同 .

1 回答

  • 3

    这是Qt中的一个错误:https://bugreports.qt.io/browse/QTBUG-43874 . 只有满足这两个条件时才会发生:

    • 在同一个查询上多次调用execBatch

    • 使用QSqlQuery :: addBindValue绑定值

    因此,您可以通过调用QSqlQuery :: bindValue来解决此错误,因此以下代码应该可以正常工作

    TOMCache::TOMCache(QObject *parent): QObject(parent) {    
        m_setWithGeoQuery.prepare("INSERT OR REPLACE INTO cache_storage(key, value, lat, lng, expiration) VALUES(?, ?, ?, ?, ?)");
    }
    
    void TOMCache::flushBuffer() {
        QSqlQuery &query = m_setWithGeoQuery;
        query.bindValue(0, m_buffer.at(0));
        query.bindValue(1, m_buffer.at(1));
        query.bindValue(2, m_buffer.at(2));
        query.bindValue(3, m_buffer.at(3));
        query.bindValue(4, m_buffer.at(4));
        if(!query.execBatch())
            qWarning() << "-- execBatch() failed: " << query.lastError().text();
        m_buffer.clear();
        m_buffer << QVariantList() << QVariantList() << QVariantList() <<     QVariantList() << QVariantList();
    }
    

相关问题