如何在两个sqlite-memory-database之间复制?

时间:2012-02-19 11:10:47

标签: qt sqlite in-memory-database

如何在Qt中的两个sqlite-memory-database之间进行复制。就像这样:

QSqlDatabase db1 = QSqlDatabase::addDatabase ("QSQLITE", "db1");
QSqlDatabase db2 = QSqlDatabase::addDatabase ("QSQLITE", "db2");
db1.setDatabaseName (":memory:");
db2.setDatabaseName (":memory:");
db1.open();
db2.open();
//add Data to db1
//do sth to copy db1's data to db2 [How]

1 个答案:

答案 0 :(得分:4)

前段时间我有类似的问题(但将MySQL数据库复制到SQLite)。 我使用了以下代码(未经过测试,full code, ll. 40-167

QString table("mytable");
QSqlDatabase srcDB=QSqlDatabase::addDatabase("QSQLITE", "db1");
QSqlDatabase destDB=QSqlDatabase::addDatabase("QSQLITE", "db2");

QSqlQuery srcQuery(srcDB);
QSqlQuery destQuery(destDB);

// get table schema
if (!srcQuery.exec(QString("SHOW CREATE TABLE %1").arg(table)))
    return false;

QString tableCreateStr;

while(srcQuery.next())
  tableCreateStr=srcQuery.value(1).toString();

// drop destTable if exists
if (!destQuery.exec(QString("DROP TABLE IF EXISTS %1").arg(table)))
     return false;

// create new one
if (!destQuery.exec(tableCreateStr))
    return false;

// copy all entries
if (!srcQuery.exec(QString("SELECT * FROM %1").arg(table)))
    return false;

while (srcQuery.next()) {
    QSqlRecord record=srcQuery.record();
    QStringList names;
    QStringList placeholders;
    QList<QVariant > values;

    for (int i = 0; i < record.count(); ++i) {
        names << record.fieldName(i);
        placeholders << ":" + record.fieldName(i);

        QVariant value=srcQuery.value(i);

        if (value.type() == QVariant::String)
            values << "\"" + value.toString() + "\"";
        else
            values << value;
    }

    // build new query
    QString queryStr;
    queryStr.append("INSERT INTO " + table);
    queryStr.append(" (" + names.join(", ") + ") ");
    queryStr.append(" VALUES (" + placeholders.join(", ") + ");");

    destQuery.prepare(queryStr);

    foreach(QVariant value, values)
        destQuery.addBindValue(value);

    if (!destQuery.exec())
        return false;
}