从表视图中删除行并从 sqlite 数据库中删除记录

Posted

技术标签:

【中文标题】从表视图中删除行并从 sqlite 数据库中删除记录【英文标题】:Deleting row from table view and record from sqlite database 【发布时间】:2012-01-23 13:28:55 【问题描述】:

我使用以下语句创建了一个 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 等等。

我的描述可能听起来令人困惑,但上述信息总是有助于轻松回答这个问题。

我添加了提醒页面,用户在其中输入数据并单击保存,然后将数据插入到数据库中。有查看提醒页面,用户可以在其中查看已保存的提醒。有 3 种不同的方式查看提醒: viewAll,viewMonthly,viewGroup.Now 在视图中,我可以使用以下语句显示每个提醒的唯一 ID:

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

loadedReminder.reminderID = sqlite3_column_int(statement, 0); 

提醒类是一个模型类,它保存在添加提醒页面中输入的所有值。

为了显示保存的提醒,我使用了一个数组并在检索每一行后添加了模型类对象,即id、name、event、date 等。并相应地填充表格视图。说如果我保存 3 个提醒,那么部分是 3 个明智的,依此类推...

现在如果我点击视图组提醒页面中的编辑按钮,那么我们知道我们可以通过点击左侧的方向按钮来删除表格视图的行(部分)。

如果我删除该行,说一行有提醒。那么与该提醒对应的数据也应该从sqlite数据库中删除。

我该怎么做,我已经完成了这个 link 听起来与我的要求相似。但它不起作用。

最后我实现了以下删除代码:

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);
    

我使用 NSLog 来检查提醒 ID 值是否正确显示:

但是,当我尝试对删除执行相同操作以检索 id 值并将该 id 值分配给 where id=? 时,出了什么问题。

它不起作用,我哪里错了?

谁能帮帮我?

【问题讨论】:

@Jennis 感谢您的关注...实际上行和记录并没有被删除 【参考方案1】:

编辑:

阅读 cmets 后,您似乎在将内存提醒 (id) 与要删除的数据库中的 id 对齐时遇到问题。数组索引不一定对应。当您使用插入语句创建提醒时,您必须立即在该调用之后调用 sqlite3_last_insert_rowid,因为它已生成。然后将您的模型类提醒ID 分配给它。然后在删除中,只需阅读提醒ID 即可组成您的删除语句。请再次记录所有内容。

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

插入后,如果您选择了提醒列表,请确保您选择了 id 列并分配给模型提醒Id,以便您知道要删除的内容。在插入和选择情况下,您需要确保最终模型的提醒ID 等于从数据库生成的 id。

首字母:

从代码看来,您正在使用已编译语句(这很好),这意味着您调用 prepare 并保存已编译语句以供重复使用。如果您正在重复使用(看不到所有代码),请确保在其上调用 sqlite3_reset。此外,如果您正在重复使用,则在完全使用它之前不应该最终确定它。

如果这不是问题,从注销 pk 和组合的 sql 语句开始。确保这是您所期望的。例如,如果它是 0,而您说 delete where pk = 0,那么它不会失败 - 它不会做任何事情,因为没有 id 为 0 的行(从 1 开始)。

之后,从 sqlite3 命令行尝试相同的语句。您可以注销模拟器正在使用的路径。

另外,注销返回码(只是不要检查 SQLITE_DONE。除了错误消息之外,我还提供提示。

希望其中一个能指引你正确的方向。

【讨论】:

感谢您的回复和回答,会尝试并回复您:) 是的,pk 值显示为 null,并且我在循环之后和关闭数据库之前重新排序了 sqlite3_finalize(compiledstatement) 让我让你更清楚我面临的问题:我添加了提醒页面,用户输入数据并点击保存,然后提醒被保存。我采用了一个名为 Reminder Class 的模型类来保存名称,事件,日期等。提醒值。 我已检索到提醒的所有值并分配给模型类变量的实例,例如提醒.Name = sqlite3_column_text(statement,1) 等... 现在我在一个方法中完成了所有这些工作,比如 -(void)loadReminders 并将所有提醒添加到数组中。只需使用该数组计数填充表视图。视图中将显示为简单地称为 [self加载提醒]【参考方案2】:

你可以这样做。这肯定会解决的

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);


在 sqlite3_bind_int() 方法中传递 id 的值。

【讨论】:

感谢您的回答,但 IdValue 是什么 id 值是你要删除数据的值 能否也请您放置id值的代码示例,提前谢谢:) 如何检索该值,请帮助我 chat.***.com/rooms/6983/iphone 我们在这个房间讨论你的问题

以上是关于从表视图中删除行并从 sqlite 数据库中删除记录的主要内容,如果未能解决你的问题,请参考以下文章

从表视图中删除行

如何在 Swift / iOS 中从 UITableView 中删除行并从 UserDefaults 中更新数组

仅拥有最新数据并从表中删除其余数据的有效方法

在Oracle中从表中删除重复行

从表视图中删除特定行

如何从表和所有引用中删除数据? [关闭]