插入sqlite3数据库

时间:2011-11-03 12:47:25

标签: iphone objective-c sqlite cocos2d-iphone

在我的应用程序中,我需要将用户保存在本地以及在线,但是当我想将用户插入其本地数据库(sqlite3)时会出现问题。

用户可以选择一个char,也是一个用户名,这是通过一个方法传递给我的dbhandler对象,如图所示。

 -(BOOL) registerUser : (NSString *) username : (int) character {

sqlite3 *db;

if(sqlite3_open([dbpath UTF8String], &db) == SQLITE_OK)
{  
    NSString *formatetStmt = [NSString stringWithFormat:@"INSERT INTO user VALUES (null, '%@', %d, 0, 1, 5, 1, 1, 1, 1, 1 ,1)", username, character];
    sqlite3_stmt *comstmt;

    if(sqlite3_prepare_v2(db, [formatetStmt UTF8String], -1, &comstmt, NULL) == SQLITE_OK)
    {                       
        sqlite3_finalize(comstmt);

        if(sqlite3_step(comstmt) == SQLITE_DONE) {
            NSLog(@"SUCCESS");
            sqlite3_finalize(comstmt);
            return YES;
        }
        else { 
            NSLog(@"NO SUCCES");
            return NO;
        }
        sqlite3_reset(comstmt);    
    }
}

NSAssert1(0, @"addMyObjectIntoDatabase: failed to prepare statement with err '%s'", sqlite3_errmsg(db));

NSLog(@"FAIL");
sqlite3_close(db);
return NO;

}

}

当我执行的代码时,它表示NO SUCCESS,但是我没有收到错误,并且没有任何内容添加到数据库中。

阿米在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

SQLite是一个C库,不适合直接使用,我建议使用Objective-C包装器,例如FMDB甚至Core Data

以下是您的示例中的一些问题。

  1. 除非打开数据库或准备语句失败,否则永远不会关闭数据库

  2. 您应该使用?绑定用户名和字符,以防止SQL注入而不是格式化字符串。

  3. 您正在使用它之前完成声明。在关闭数据库之前完成语句后,将完成结束。

  4. 您不知道错误代码,因为您没有从sqlite3_step存储它是一个int。

  5. 您正在提前返回该方法而不关闭数据库。你应该设置一个成功标志,然后确保你的数据库实际打开,然后关闭它然后在结尾处返回标志。


  6. -(BOOL) registerUser : (NSString *) username : (int) character {
        //If using the same database for more operations often you may want to just keep
        //the db open in a centralized location while the app is running
        sqlite3 *db;
    
        if(sqlite3_open([dbpath UTF8String], &db) == SQLITE_OK)
        {  
            //You should bind these values to prevent SQL Injection
            NSString *formatetStmt = [NSString stringWithFormat:@"INSERT INTO user VALUES (null, '%@', %d, 0, 1, 5, 1, 1, 1, 1, 1 ,1)", username, character];
            sqlite3_stmt *comstmt;
    
            if(sqlite3_prepare_v2(db, [formatetStmt UTF8String], -1, &comstmt, NULL) == SQLITE_OK)
            {                       
                // You are finalizing a statement before using it move this
                // to after your done with the statement
                sqlite3_finalize(comstmt);
                //Try int status = sqlite3_step(comstmt)
                if(sqlite3_step(comstmt) == SQLITE_DONE) {
                    NSLog(@"SUCCESS");
                    sqlite3_finalize(comstmt);
                    return YES;
                }
                else { 
                    NSLog(@"NO SUCCES");
                    return NO;
                }
                sqlite3_reset(comstmt); //<- Never gets called because of return
                                        // statement but you should finalize here
            }
        }
    
        NSAssert1(0, @"addMyObjectIntoDatabase: failed to prepare statement with err '%s'", sqlite3_errmsg(db));
    
        NSLog(@"FAIL");
        sqlite3_close(db); // <-Never gets called unless statement fails to prepare
        return NO;
    
    }