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

标签 c++ qt sqlite blackberry-10 qsqlquery

我有一个类需要重复执行批量插入。 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();
}

我有几个问题:

  1. 每次调用 execBatch() 是否都需要创建和销毁 QSqlQuery?

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

  3. 第一种情况下文件大小很大怎么办? (只有2张 table ,另一张是空的)

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

编辑:我试图避免每次解析 SQL,所以我尝试保持 m_setWithGeoQuery 不变,并在flushBuffer()中复制它:

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

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

最佳答案

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

  • 对同一个查询多次调用 execBatch
  • 使用 QSqlQuery::addBindValue 绑定(bind)值

因此,您可以通过调用 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();
}

关于c++ - SQLite 和 QSqlQuery - 多次调用 execBatch() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22171992/

相关文章:

c++ - 头文件包含在纯虚类中

c++ - std::set 包含对与自定义​​比较器

sqlite - QSqlTableModel Submitall,但数据库未更新

go - 如何从 golang 中的 sql 解析 *time.Time?

android - 删除行后 SQLite id 行不遵循顺序

c++ - 错误 : C2059: syntax error : '{'

c++ - 树,无法正确删除节点

c++ - Dialog 关闭后嵌入式 QGraphicsView 不隐藏

c++ - Qt - 使用由按钮控制的线程的简单示例

Qt双免费或损坏