我知道在SQLite中有一个功能可以转储所有表(到文件" createDBTablesScript.sql"),其中包含:
sqlite> .output createDBTablesScript.sql
sqlite> .dump
sqlite> .quit
有没有办法在QT中做到这一点? 这样的事情(!这不工作!):</ p>
QString queryString(".output createDBTablesScript.sql .dump");
QSqlQuery query( m_db );
bool checkQueryExcecution = query.exec( queryString );
之后我也想从QT运行脚本,例如:
QString createDBTablesScriptString("run createDBTablesScript.sql");
QSqlQuery query( m_db );
bool checkQueryExcecution = query.exec( createDBTablesScriptString );
答案 0 :(得分:7)
.dump
命令在sqlite
命令行应用程序中实现,而不是在SQLite库本身中实现。 .dump
使用标准SQL查询从数据库中提取所需的所有内容。你也可以这样做,但它不仅仅是3行。
看起来有点像:
QSqlQuery query;
QStringList tables;
query.prepare("SELECT * FROM sqlite_master");
while (query.next())
{
qDebug() << query.value("sql").toString();
if (query.value("type").toString() == "table")
tables << query.value("name");
}
static const QString insert = QStringLiteral("INSERT INTO %1 (%2) VALUES (%3);");
QStringList columns;
QStringList values;
QSqlRecord record;
bool first = true;
foreach (const QString& table, tables)
{
first = true;
query.prepare(QString("SELECT * FROM [%1]").arg(table));
while (query.next())
{
record = query.record();
for (int i = 0; i < record.count(); i++)
{
if (first)
columns << record.fieldName(i);
values << record.value(i);
}
first = false;
qDebug() << insert.arg(table).arg(columns.join(", ")).arg(values.join(", "));
}
}
很少注意到:
我是从头开始写的,没有测试过,所以可能会有一些错误,但你会得到一般的想法。
这不会包含.dump
生成的其他查询,例如开头的BEGIN;
和PRAGMA foreign_keys = 0;
,最后是COMMIT;
。< / p>
.dump
可能会在某些特殊情况下产生更多查询,我不知道。我只是尝试在我的测试数据库上运行.dump
,其中包含2个表,这些都是我发现的结果。
答案 1 :(得分:1)
最后我这样做了:
/**
* This function should do something similar to :
*
* sqlite> .output "t_fileName" --f.e. "createEmptyDBTablesScript.sql"
* sqlite> .dump
*
* this function dumps not the values, it dumps only the table schemas (the CREATE TABLE statement)!
*/
bool
DBAccess::dumpDBTableSchemasToFile
(
const QString &t_fileName,
const QString &t_createTableStatementSeperator /* = QString("--;;") */
)
{
bool r_dumpingSuccessfull = false;
if( m_db.open() ) //QSqlDatabase m_db; //qt connection to sqlite database
{
qDebug() << "Dump the Database Schemas to file "+ t_fileName;
QFile outputFile(t_fileName);
outputFile.open(QIODevice::WriteOnly);
/* Check if File opening was OK */
if( !outputFile.isOpen() )
{
qDebug() << "- Error, unable to open '" << t_fileName << "' to dump SQL for table creation!";
return r_dumpingSuccessfull;
}
/* Point a QTextStream object at the file */
QTextStream outStream(&outputFile);
/* Ask the 'sqlite_master' table of the sqlite Database with a SELECT statement for all tables, the 'sql' column holds the sql-CREATE TABLE statement which created the current table. */
QSqlQuery sqlite_masterQuery( m_db );
if( !sqlite_masterQuery.exec( "SELECT * FROM sqlite_master" ) )
{
//Something with the SQL-Query or the DB-connection is wrong.
QString lastError = sqlite_masterQuery.lastError().text();
qDebug() << lastError;
return r_dumpingSuccessfull;
}
else
{
//Here we got some valid results from the sql-query above
do
{
QString tableName = sqlite_masterQuery.value("name").toString();
if( sqlite_masterQuery.value("type").toString() == "table" && tableName != "sqlite_sequence" )//The "sqlite_sequence" table is an internal table used to help implement AUTOINCREMENT
{
/* Write the 'sql' column value to the file, the 'sql' column value represent the 'CREATE TABLE xyz...' sql statement */
outStream << sqlite_masterQuery.value("sql").toString();
outStream << "\n";
outStream << t_createTableStatementSeperator;
outStream << "\n";
r_dumpingSuccessfull = true;
}
} while( sqlite_masterQuery.next() );
}
outputFile.close();/* Close the dump-file */
}
return r_dumpingSuccessfull;
}
这是经过测试和运作的。 有了这个:
bool
DBAccess::createDBTableSchemasFromFile
(
const QString &t_fileName,
const QString &t_createTableStatementSeperator /* = QString("--;;") */
)
{
bool r_creationSuccessfull = false;
if( m_db.open() )
{
qDebug() << "Creating the empty tables of the Database from file "+ t_fileName;
QFile outputFileRead( t_fileName );
if( !outputFileRead.open( QIODevice::ReadOnly | QIODevice::Text ) )
return r_creationSuccessfull;
QTextStream sqlTableCreationScriptTextStream( &outputFileRead );
QString sqlTableCreationDataWholeString = sqlTableCreationScriptTextStream.readAll();
QStringList seperateCreatTableStatementsList = sqlTableCreationDataWholeString.split( t_createTableStatementSeperator );
foreach( const QString& creatTableStatement, seperateCreatTableStatementsList )
{
qDebug() << creatTableStatement;
if( creatTableStatement.simplified().isEmpty() )
continue;
QSqlQuery query( m_db );
if( !query.exec( creatTableStatement ) )
{
QString lastError = query.lastError().text();
qDebug() << lastError;
r_creationSuccessfull = false;
break;
}
r_creationSuccessfull = true;
}
}
return r_creationSuccessfull;
}
也可以从转储的sql中重新创建db。
正如Googie已经说过的那样:“你也可以这样做,但它不仅仅是3行。”