我有一个需要重复执行批量插入的类。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));
...
令人惊讶的是,它不起作用。它的行为与第一个片段相同。