【问题标题】:How to sqlite .dump using Qt如何使用 Qt sqlite .dump
【发布时间】:2014-10-07 19:32:51
【问题描述】:

我想使用 Qt 之类的 .dump 表,

sqlite> sqlite3 a.db ".dump" | sqlite3 b.db

我正在使用转储来恢复损坏的表或数据库。 但我想将转储与 Qt 一起使用。 所以我制作了这段代码

mainDb = QSqlDatabase::addDatabase( "QSQLITE" , "first" );
mainDb.setDatabaseName( "main.db" );
mainDb.open();

copyDb = QSqlDatabase::addDatabase( "QSQLITE" , "second" );
copyDb.setDatabaseName( "copy.db" );
copyDb.open();

QSqlQuery mainQuery( mainDb );
QSqlQuery subQuery( copyDb );

bool ret = subQuery.exec( "create table contents_list("
                          "id      varchar(128) primary key not null,"
                          "data    varchar(2048) );" );
if( !ret )
{
    qDebug() << subQuery.lastError().text();
}

static const QString QUERYFORMAT( "INSERT INTO CONTENTS_LIST( id, data ) VALUES( '%1' , '%2' )" );

mainQuery.exec( "select * from contents_list" );
QSqlRecord rec = mainQuery.record();
QString id, data;
QString queryString;

while( mainQuery.next() )
{
    id = mainQuery.value( rec.indexOf( "id" ) ).toString();
    data = mainQuery.value( rec.indexOf( "data" ) ).toString(); 
    qDebug() << id << " " << data ;

    queryString = QUERYFORMAT.arg( id, data );
    ret = subQuery.exec( queryString );

    if( !ret )
    {
        qDebug() << subQuery.lastError().text();
    }
}

mainQuery.exec( "delete from contents_list" );

subQuery.exec( "select * from contents_list" );
rec = subQuery.record();

while( subQuery.next() )
{
    id = subQuery.value( rec.indexOf( "id" ) ).toString();
    data = subQuery.value( rec.indexOf( "data" ) ).toString(); 
    qDebug() << id << " " << data ;

    queryString = QUERYFORMAT.arg( id, data );
    ret = mainQuery.exec( queryString );

    if( !ret )
    {
        qDebug() << mainQuery.lastError().text();
    }
}
subQuery.exec( "drop table contents_list" );

mainDb.close();
copyDb.close();

这段代码运行正常,但是当记录数超过10000时运行时间非常长~。 如何减少运行时间,或以其他方式恢复损坏的数据库。

对不起我的英语水平。

谢谢。

【问题讨论】:

    标签: qt sqlite


    【解决方案1】:

    在QSqlQuery subQuery( copyDb );之后添加:

    mainQuery.exec("BEGIN;");
    subQuery.exec("BEGIN;");
    

    在mainDb.close();之前添加:

    mainQuery.exec("COMMIT;");
    subQuery.exec("COMMIT;");
    

    【讨论】:

    • 只是为了兴趣,为什么在子查询之前提交主查询?
    • 没有特别的原因。 @kisang 在他的原始代码中首先关闭了mainDb,所以我认为这是自然的先提交它。
    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 2020-03-30
    • 2020-10-07
    • 2011-01-20
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多