更新后查询SQLite数组

时间:2011-04-05 13:05:15

标签: iphone arrays sqlite uitableview

我有一个带有2个UITableViews的标签栏应用程序。在选项卡1中,我有一个UITableView,其中填充了来自Sqlite数据库的Todo对象数组。每个Todo对象的状态都可以通过其详细视图中的按钮进行更新; '完成'或'进行中' - 如果Todo对象已标记为'完成',则更新SQlite数据库为'1';如果标记为'正在进行',则更新为'0'。我觉得这很好用(虽然它在退出应用程序后不会持续存在)。

但是,在标签2中我有另一个UITableView,我想只显示标记为“完整”的项目。

这是否需要另一个单独的Sqlite调用(从todo中选择*,其中complete ='1'),然后a 单独的TodoFav对象数组填充Tab 2中的表格?如果是这样,Tab 2如何知道Tab 1已被更新并保存? - 我认为目前它只能在退出时保存(尽管退出后这似乎并不存在)。

任何帮助都会非常感激,我现在​​已经潜伏了一段时间,并且经过长时间的努力寻找答案无济于事!非常感谢。

修改

脱水代码以在退出时保存更新:

- (void) dehydrate {
if (dirty) { // If the todo is “dirty” meaning the dirty property was set to YES, we will need   to save the new data to the database.
if (dehydrate_statment == nil) {
    const char *sql = "UPDATE todo SET priority = ?,complete =? WHERE pk=?";
    if (sqlite3_prepare_v2(database, sql, -1, &dehydrate_statment, NULL) != SQLITE_OK) {
        NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
    }
}
// Bind our variables to each of the “?”‘s.  Notice the order.  
// The numbers represent the question marks from left to right (1 being the first, 2 being the second, 3 being the third)
sqlite3_bind_int(dehydrate_statment, 3, self.primaryKey);
sqlite3_bind_int(dehydrate_statment, 2, self.status);
sqlite3_bind_int(dehydrate_statment, 1, self.priority);
int success = sqlite3_step(dehydrate_statment);

if (success != SQLITE_DONE) {
    NSAssert1(0, @"Error: failed to save priority with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_reset(dehydrate_statment);
dirty = NO;
}       
}

按钮的代码改为完成:

- (void)updateStatus:(NSInteger)newStatus {
self.status = newStatus;
dirty = YES;     // Signifies that the todo has been altered and will need to be saved to the database.
}

尝试第二次查询数据库中的“已完成”(status ='1')项目:

- (NSMutableArray *)todosComplete {

NSMutableArray *todoCompleteArray = [[NSMutableArray alloc] init];
self.todosComplete = todoCompleteArray;
[todoCompleteArray release];

NSMutableArray *retval = [[[NSMutableArray alloc] init] autorelease];
NSString *query = @"select * from todo where status='1'";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
    while (sqlite3_step(statement) == SQLITE_ROW) {
        int primaryKey = sqlite3_column_int(statement, 0);
        TodoComplete *tdC = [[TodoComplete alloc] initWithPrimaryKey:primaryKey database:database];
        [todosComplete addObject:tdC];
        [tdC release];
    }
    sqlite3_finalize(statement);
}
return retval;

}

最后一件事,在app delegate中初始化,似乎工作正常:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

// Override point for customization after application launch.

[self createEditableCopyOfDatabaseIfNeeded];
[self initializeDatabase];
//[self initializeDatabaseFiltered];

// Add the navigation controller's view to the window and display.
[self.window addSubview:navigationController.view];
[self.window addSubview:tabController.view];
[self.window makeKeyAndVisible];

return YES;

}

再次感谢!!!对不起,很长的帖子,非常感谢任何帮助。我知道我错过了一些明显的东西 - 脱水需要立即开始吗?我可能没有正确查询数据库中的过滤项目或其他东西!?

1 个答案:

答案 0 :(得分:0)

我不是sqlite的专家,但你保存的方式似乎过于复杂。当我按下保存按钮时,我认为你可以执行以下操作(这是未经测试的,我需要一点语法修复,并且我在那里有'buttonState'来指示按钮按下之前它是0还是1,所以调整因此......这也假设行==主键,因此可能需要进行调整。我也不确定开放的数据库连接是否在方法之间持续(不是说它不是,只是我不知道)所以当你去调用完成的结果时,可能需要打开一个数据库连接[和你在打开它的最后一个方法中关闭了它:

-(void)didPushButton{
    //something to identify which indexPath.row held the button that was selected
    sqlite3 *pref = [self getNewDBConnection];
    sqlite3_stmt *progStatement = nil;
    NSString *setProg = [NSString stringWithFormat:@"UPDATE todo SET complete=%d WHERE pk=%d",-buttonState+1,indexPath.row];
    char * errorMsg2;
    if(sqlite3_exec(pref,[setProg UTF8String],NULL,NULL,&errorMsg2)!=SQLITE_OK)
    {NSLog(@"error setting completion");} 
    else {NSLog(@"set status for pk:%d",indexPath.row);}
    sqlite3_finalize(progStatement);
    sqlite3_close(pref);
    buttonState=-buttonState+1;
    }