2012-06-08 13 views
2

Я пишу приложение для контактной книги. Контакты хранятся в базе данных qsqlite и отображаются с использованием QSqlQueryModel.Не удалось обновить базу данных QSqlite - заблокирована база данных не удалось получить строку

QueryModel по умолчанию запускает запрос, который отображает все контакты. Контакты можно редактировать и удалять.

Когда пользователь вводит имя в поле поиска, запускается SearchQuery и отображаются только те контакты, которые соответствуют условиям поиска. Проблема в том, что я не могу редактировать или удалять эти контакты. Я получаю сообщение об ошибке, которое говорит, что база данных заблокирована, и не может получить строку.

Я не понимаю, почему это происходит. Если я могу редактировать/удалять результаты запроса по умолчанию, то я должен иметь возможность редактировать/удалять результаты поискового запроса.

Ниже приведен код:

  • Конструктор

  • Поиск Контакт

  • Удаление Контакт

Constructor (соответствующие части)

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.")); 
} 

Я бы очень признателен за любую помощь в этом. Спасибо :)

ответ

0

Как ни странно, код работает отлично после устранения этой строки кода:

ui->listView->scrollTo(index); 
+0

бы держать эту строку и добавить 'fetchMore()' помочь? Мне действительно интересно выяснить, почему это не работает. Линия 'scrollTo', вероятно, только выдает проблему - ее документы для удаления по основному вопросу, который я думаю. Вы можете сделать прокрутку без проблем. –

3

Единственное, что приходит на ум - это необходимость обеспечить получение всех результатов запроса. Открытый запрос, вероятно, поддерживает блокировку базы данных. Может быть.

Начало step6, таким образом, выглядит следующим образом:

//STEP 6: If results, update model, show first result. 
Model->setQuery(SearchQuery); 
while (Model->canFetchMore()) { 
    Model->fetchMore(); 
} 

Не больно, чтобы попробовать, что, я думаю.

Смежные вопросы