Удаление строки из табличного представления и записи из базы данных sqlite - PullRequest
2 голосов
/ 23 января 2012

Я создал таблицу sqlite, используя следующую инструкцию:

"CREATE TABLE IF NOT EXISTS reminders (ID INTEGER PRIMARY KEY,Name VARCHAR(64), Event VARCHAR(64), Date VARCHAR(64), Bfr VARCHAR(64), Val VARCHAR(64),Num VARCHAR(64), Bod VARCHAR(400) ,Grp VARCHAR(64))";

Я успешно вставил данные и извлек данные из базы данных sqlite и отобразил напоминания в виде напоминаний слишком программно!

Но я поражен удалением записей из базы данных sqlite. Я имею в виду, что я использовал класс модели для хранения таких значений, как имя, событие, дата и т. Д. На странице добавления напоминания я назначил значения для переменных, объявленных вкласс модели, то есть

textField.text = remClass.Name и т. д.

Мое описание может показаться запутанным, но приведенная выше информация всегда полезна, чтобы легко ответить на этот вопрос.1011 * Я добавил страницу напоминания, где пользователь вводит данные и нажимает кнопку Сохранить, затем данные вставляются в базу данных. Существует страница «Просмотр напоминаний», где пользователь может просматривать сохраненное напоминание. В нем есть 3 различных способа просмотра напоминаний: viewAll, viewMonthly, viewGroup. Теперь все, что мне удалось отобразить уникальный идентификатор для каждого напоминания, используяg следующее утверждение:

ReminderClass *loadedReminder = [[ReminderClass alloc] init];

loadedReminder.reminderID = sqlite3_column_int(statement, 0); 

Где класс напоминания - это класс модели, который содержит все значения, введенные на странице добавления напоминания.

Для отображения сохраненного напоминания я использовалмассив и добавил объект класса модели после извлечения каждой строки, то есть идентификатор, имя, событие, дата и т. д. и соответственно заполнил представление таблицы. Скажем, если я сохраню 3 напоминания, то разделы будут 3, как мудрый и так далее ...

Теперь, если я нажму кнопку редактирования на странице напоминаний группы представлений, то, как мы знаем, мы можем удалить строку (раздел) представления таблицы, нажав кнопку ориентации слева.

Если я удаляюстрока, скажем строка с напоминанием. Затем данные, соответствующие этому напоминанию, также должны быть удалены из базы данных sqlite.

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

Наконец, я реализовал следующий код для удаления:

if (editingStyle == UITableViewCellEditingStyleDelete) 
    {        
        [self.grpArray objectAtIndex:indexPath.section];

        if(sqlite3_open([databasePath UTF8String], &remindersDB)==SQLITE_OK)
        {   
            sqlite3_stmt *compiledstatement;

            int pk = sqlite3_column_int(compiledstatement, 0);
            NSString *querySQL = [NSString stringWithFormat:@"delete from reminders where ID = %i",pk];

            const char *sqlstmt=[querySQL UTF8String];

            if(sqlite3_prepare_v2(remindersDB, sqlstmt, -1, &compiledstatement, NULL)==SQLITE_OK)
            {                
                if(SQLITE_DONE != sqlite3_step(compiledstatement))

                    NSAssert1(0,@"Error while creating delete statement => %s",sqlite3_errmsg(remindersDB));
            }
            NSLog(@"delete DONE");
            sqlite3_finalize(compiledstatement);
        }
        sqlite3_close(remindersDB);

        [self.gTable reloadData];
    }

КОД ПОЛУЧЕНИЯ:

-(void)loadgReminders
{

    EventsReminderAppDelegate *appDelegate = (EventsReminderAppDelegate *)[[UIApplication sharedApplication]delegate];
    NSLog(@"String = %@",appDelegate.groupString);

    self.grpArray = nil;
    self.grpArray = [[NSMutableArray alloc]init];

    //Retrieve the group of reminder
    const char *thePath = [self.databasePath UTF8String];
    sqlite3_stmt *statment;

    if (sqlite3_open(thePath, &remindersDB) == SQLITE_OK)
    {
        NSString *getQuery = [NSString stringWithFormat:@"SELECT * FROM reminders WHERE Grp = '%@' ORDER BY Date ASC",appDelegate.groupString];
        const char *sqlite_stmt = [getQuery UTF8String];

        if (sqlite3_prepare_v2(self.remindersDB, sqlite_stmt, -1, &statment, NULL) == SQLITE_OK)
        {
            while (sqlite3_step(statment) == SQLITE_ROW) 
            {
                ReminderClass *remind = [[ReminderClass alloc]init];
                remind.reminderID = sqlite3_column_int(statment, 0);
                **NSLog(@"reminderID=%d",remind.reminderID);**
                remind.Name = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 1)];
                remind.Event = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 2)];
                remind.Date = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 3)];
                remind.numDays = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 4)];
                remind.selString = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 5)];
                remind.number = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 6)];
                remind.msgBody = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 7)];
                remind.remGroup = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 8)];

                NSDateFormatter *dateFormat = [[[NSDateFormatter alloc]init]autorelease];
                [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                NSDate *date = [dateFormat dateFromString:remind.Date];
                [dateFormat setDateFormat:@"MMMM dd"];
                NSString *dateVal = [dateFormat stringFromDate:date];
                remind.Date = dateVal;

                [self.grpArray addObject:remind];

                [remind release];
            }

            sqlite3_finalize(statment);
        }

        sqlite3_close(remindersDB);
    }
}

ThПрежде чем я использовал NSLog для проверки правильности отображения значений идентификатора напоминания или нет, он отображается следующим образом:

enter image description here

Но что не так, когда я пытаюсь сделать то же самое с удалением вполучить значения идентификатора и назначить это значение идентификатора где id =?.

Это не работает, где я не прав?

Может кто-нибудь, пожалуйста, помогите мне?

Ответы [ 2 ]

2 голосов
/ 23 января 2012

EDIT:

После прочтения комментариев кажется, что у вас возникли проблемы с выравниванием напоминания (идентификатора) в памяти и идентификатора в базе данных для удаления. Индекс массива не обязательно соответствует. Когда вы создаете напоминание с помощью оператора вставки, вы должны сразу же следовать этому вызову с помощью вызова sqlite3_last_insert_rowid, поскольку он сгенерирован. Затем присвойте ему напоминание модели классов. Затем, при удалении, просто прочитайте напоминание, чтобы составить оператор удаления. Еще раз, пожалуйста, войдите все.

http://www.sqlite.org/capi3ref.html#sqlite3_last_insert_rowid

После вставки, если вы выбрали список напоминаний, убедитесь, что вы выбираете столбец идентификатора и присваиваете напоминание модели, чтобы вы знали, что нужно удалить. И в случае вставки, и в случае выбора вы должны убедиться, что в конечном итоге напоминание модели совпадает с сгенерированным идентификатором из базы данных.

ПЕРВИЧНЫЙ:

Из кода похоже, что вы используете скомпилированный оператор (что хорошо), что означает, что вы вызываете prepare и сохраняете скомпилированный оператор для повторного использования. Если вы используете повторно (не видите весь код), убедитесь, что вы вызвали sqlite3_reset для него. Кроме того, если вы используете повторно, вы не должны завершать его, пока не закончите с ним.

Если это не проблема, начните с выхода из системы pk и составленного оператора sql. убедитесь, что это то, что вы ожидаете. Например, если это 0, и вы говорите «удалить», где pk = 0, то это не сработает - просто ничего не будет делать, потому что нет строки с идентификатором 0 (начинается с 1).

После этого попробуйте тот же оператор из командной строки sqlite3. Вы можете выйти из пути, который использует симулятор.

Кроме того, выйдите из кода возврата (только не проверяйте SQLITE_DONE. Это в дополнение к сообщению об ошибке может дать подсказку.

Надеюсь, один из них укажет вам правильное направление.

1 голос
/ 23 января 2012

Вы можете сделать это так.Это определенно сработает

if (editingStyle == UITableViewCellEditingStyleDelete) 
        {

            NSString *dbPath = [self getDBPath];

            NSString *couponIdValue = [listOfCouponId objectAtIndex:indexPath.row];


            if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {

                const char *sql = "delete from reminders where ID = ?";
                sqlite3_stmt *deletestmt;
                if(sqlite3_prepare_v2(database, sql, -1, &deletestmt, NULL) != SQLITE_OK) {
                    NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
                }



                sqlite3_bind_int(deletestmt, 1, [IdValue intValue]);


                if (SQLITE_DONE != sqlite3_step(deletestmt)) 
                    NSAssert1(0, @"Error while deleting. '%s'", sqlite3_errmsg(database));


                sqlite3_reset(deletestmt);

}

передать значение id в методе sqlite3_bind_int ().

...