我正在寫一個聯繫簿應用程序。聯繫人存儲在qsqlite數據庫中,並使用QSqlQueryModel顯示。無法更新QSqlite數據庫 - 數據庫鎖定無法獲取行
QueryModel默認運行一個顯示所有聯繫人的查詢。聯繫人可以編輯和刪除。
當用戶在搜索字段中輸入名稱時,會運行SearchQuery並僅顯示與搜索條件匹配的聯繫人。問題是我無法編輯或刪除這些聯繫人。我得到一個錯誤,說數據庫被鎖定,無法獲取行。
我不明白爲什麼會發生這種情況。如果我可以編輯/刪除默認查詢的結果,那麼我應該可以編輯/刪除搜索查詢的結果。
下面是代碼:
構造
在搜索聯繫人
拆卸觸點
構造函數(相關部分)
OpenDatabase();
DefaultModelQuery.append("SELECT Id,FirstName||' '||LastName AS FullName,");
DefaultModelQuery.append("FirstName,LastName,Email,HomeNumber,WorkNumber,MobileNumber,Address,City,Country,Birthdate FROM Contacts ");
DefaultModelQuery.append("ORDER BY FirstName;");
QSqlQuery Query(DefaultModelQuery);
ActiveQuery = Query;
Model = new QSqlQueryModel(this);
Model->setQuery(ActiveQuery);
ui->listView->setModel(Model);
ui->listView->setModelColumn(1);
搜索聯繫
void Contacts::SearchContact()
{
/*1. Read Search Term
2. Decide Type
3. Generate Query
4. Execute Query.
5. If No results, return
6. If resutls, update Model, show first result.
*/
//STEP 1: Read Search Term.
QString SearchTerm = ui->SearchLineEdit->text();
if(SearchTerm.isEmpty())
return;
/*STEP 2. Decide Type
Type n : Name
Type e : Email
Type p : Number
*/
char QueryType;
if(SearchTerm.contains(QRegExp("[A-za-z-]+")))
{
if(SearchTerm.contains("@"))
QueryType = 'e';
else
QueryType = 'n';
}else if(SearchTerm.contains(QRegExp("[0-9]+")))
QueryType = 'p';
else
QueryType = 'n';
//STEP 3: Generate Query
QSqlQuery SearchQuery;
switch(QueryType)
{
case 'n':
{
QStringList Names = SearchTerm.split(" ");
if(Names.size()>=2)
{
qDebug()<<QString("Searching for %1 %2").arg(Names.first(),Names.last());
SearchQuery.prepare("SELECT Id,FirstName||' '||LastName AS FullName,FirstName,LastName,Email,HomeNumber,MobileNumber,WorkNumber,Address,City,Country,Birthdate FROM CONTACTS WHERE FirstName=:f AND LastName=:l ORDER BY FirstName");
SearchQuery.bindValue(":f",Names.first());
SearchQuery.bindValue(":l",Names.last());
}else
{
qDebug()<<QString("Searching for %1").arg(Names.first());
SearchQuery.prepare("SELECT Id,FirstName||' '||LastName AS FullName,FirstName,LastName,Email,HomeNumber,MobileNumber,WorkNumber,Address,City,Country,Birthdate FROM CONTACTS WHERE FirstName=:f OR LastName=:l ORDER BY FirstName");
SearchQuery.bindValue(":f",Names.first());
SearchQuery.bindValue(":l",Names.first());
}
break;
}
case 'e':
{
QString Email = SearchTerm.trimmed();
SearchQuery.prepare("SELECT Id,FirstName||' '||LastName AS FullName,FirstName,LastName,Email,HomeNumber,MobileNumber,WorkNumber,Address,City,Country,Birthdate FROM CONTACTS WHERE Email=:e ORDER BY FirstName");
SearchQuery.bindValue(":e",Email);
break;
}
case 'p':
{
QString Number = SearchTerm.trimmed();
SearchQuery.prepare("SELECT Id,FirstName||' '||LastName AS FullName,FirstName,LastName,Email,HomeNumber,MobileNumber,WorkNumber,Address,City,Country,Birthdate FROM CONTACTS WHERE HomeNumber=:h OR WorkNumber=:w OR MobileNumber=:m ORDER BY FirstName");
SearchQuery.bindValue(":h",Number);
SearchQuery.bindValue(":m",Number);
SearchQuery.bindValue(":w",Number);
break;
}
}
//STEP 4: Execute Query
if(!SearchQuery.exec())
{
qDebug()<<QueryType<<": "<<SearchQuery.lastError().text();
QMessageBox::information(this,
tr("Search Error"),
tr("The following error occured while trying to search contacts:\nError: %1").arg(SearchQuery.lastError().text()));
return;
}
//STEP 5: If no results, return;
/*Note:
I used the QSqlQuery::first() method here to check if there are any result or not.
I doubt this is efficient, because the function probably invovles unnecessary steps & resources.
So the following code could be made more efficient.
I can't use QSqlQuery::size() because it always returns -1.
*/
if(!SearchQuery.first())
{
QMessageBox::information(this,
tr("No Results Found"),
tr("No results were found for \"%1\"").arg(SearchTerm));
return;
}
//STEP 6: If results, update model, show first result.
Model->setQuery(SearchQuery);
QModelIndex index = Model->index(0,1);
DisplayContact(index);
ui->listView->scrollTo(index);
SetView(Contacts::View_DisplaySearchResultsView);
}
拆卸觸點
void Contacts::RemoveContact()
{
if(SelectedRecordId!=-1)
{
if(QMessageBox::information(this,
"Confirm Removal",
"Are you sure you want to remove this contact from your list?",
QMessageBox::Yes|QMessageBox::No)==QMessageBox::No)
return;
QSqlQuery DeleteQuery;
DeleteQuery.prepare("DELETE FROM Contacts WHERE Id = :i;");
DeleteQuery.bindValue(":i",SelectedRecordId);
if(!DeleteQuery.exec())
{
qDebug()<<DeleteQuery.lastError().text();
QMessageBox::warning(this,
tr("Error Removing Contact"),
tr("An error occured while trying to remove this contact."));
}else
{
SelectedRecordId =-1;
clear();
SetView(Contacts::View_AddContactView);
Model->setQuery(ActiveQuery);
UpdateContactCount();
}
}else
QMessageBox::warning(this,
tr("No Record Selected"),
tr("Unexpected Error: Remove Contact Operation is being attempted while no contact is selected."));
}
我真的很感激任何幫助。謝謝:)
會保持這一行並添加'fetchMore()'幫助嗎?我真的很想搞清楚爲什麼它不起作用。 「scrollTo」這行可能只是暴露了一個問題 - 它的移除論文是我認爲的潛在問題。你應該可以做到沒有問題的滾動。 –