2010-09-17 53 views
7

我有一個文件包含幾個我想用來初始化一個新的sqlite3數據庫文件的sql語句。顯然,sqlite3只能通過sqlite3_exec函數在一個查詢中處理多個語句,而不能通過prepare/step/finalize函數處理。這很好,但我想直接使用QtSQL api而不是c api。通過QSqlQuery載入相同的初始化文件只執行第一條語句,就像直接使用sqlite3 API中的prepare/step/finalize函數一樣。有沒有辦法讓QSqlQuery運行多個查詢,而不必對每個語句單獨調用query.exec()?QSqlQuery中使用sqlite3驅動程序的多個sql語句

回答

9

如Qt文檔明確闡述了QSqlQuery::prepare()QSqlQuery::exec()

SQLite的,查詢字符串可以一次只包含一個聲明。 如果給出多個語句,則該函數返回false。

正如你已經猜到,這個限制的唯一已知的解決方法是讓所有的sql語句由一些字符串分隔開來,將語句拆分並在循環中執行它們中的每一個。

請參見下面的示例代碼(使用「;」作爲分隔符,並假定相同的字符不在查詢內部使用。這種缺乏通用性,因爲您可能在/ insert /更新語句):

QSqlDatabase database; 
QSqlQuery query(database); 
QFile scriptFile("/path/to/your/script.sql"); 
if (scriptFile.open(QIODevice::ReadOnly)) 
{ 
    // The SQLite driver executes only a single (the first) query in the QSqlQuery 
    // if the script contains more queries, it needs to be splitted. 
    QStringList scriptQueries = QTextStream(&scriptFile).readAll().split(';'); 

    foreach (QString queryTxt, scriptQueries) 
    { 
     if (queryTxt.trimmed().isEmpty()) { 
      continue; 
     } 
     if (!query.exec(queryTxt)) 
     { 
      qFatal(QString("One of the query failed to execute." 
         " Error detail: " + query.lastError().text()).toLocal8Bit()); 
     } 
     query.finish(); 
    } 
} 
+1

怎麼樣'選擇 「你好,世界FROM表」'或'SELECT * FROM表 - 你好; world'? – yrHeTaTeJlb 2017-03-20 08:49:11

1

我寫了一個簡單的函數來從文件中讀取SQL並一次執行一條語句。

/** 
* @brief executeQueriesFromFile Read each line from a .sql QFile 
* (assumed to not have been opened before this function), and when ; is reached, execute 
* the SQL gathered until then on the query object. Then do this until a COMMIT SQL 
* statement is found. In other words, this function assumes each file is a single 
* SQL transaction, ending with a COMMIT line. 
*/ 

void executeQueriesFromFile(QFile *file, QSqlQuery *query) 
{ 
    while (!file->atEnd()){ 
     QByteArray readLine=""; 
     QString cleanedLine; 
     QString line=""; 
     bool finished=false; 
     while(!finished){ 
      readLine = file->readLine(); 
      cleanedLine=readLine.trimmed(); 
      // remove comments at end of line 
      QStringList strings=cleanedLine.split("--"); 
      cleanedLine=strings.at(0); 

      // remove lines with only comment, and DROP lines 
      if(!cleanedLine.startsWith("--") 
        && !cleanedLine.startsWith("DROP") 
        && !cleanedLine.isEmpty()){ 
       line+=cleanedLine; 
      } 
      if(cleanedLine.endsWith(";")){ 
       break; 
      } 
      if(cleanedLine.startsWith("COMMIT")){ 
       finished=true; 
      } 
     } 

     if(!line.isEmpty()){ 
      query->exec(line); 
     } 
     if(!query->isActive()){ 
      qDebug() << QSqlDatabase::drivers(); 
      qDebug() << query->lastError(); 
      qDebug() << "test executed query:"<< query->executedQuery(); 
      qDebug() << "test last query:"<< query->lastQuery(); 
     } 
    } 
} 
相關問題