插入sqlite3数据库

问题描述 投票:0回答:1

在我的应用程序中,我需要保存用户本地以及在线,但问题出现在我想将用户插入其本地数据库(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,但是我没有收到错误,并且没有任何内容添加到数据库中。

阿美在这里做错了什么?

iphone objective-c sqlite cocos2d-iphone
1个回答
1
投票

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

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

  1. 除非打开数据库或准备语句失败,否则永远不会关闭数据库
  2. 您应该使用?绑定用户名和字符以防止SQL注入而不是格式化字符串。
  3. 您在使用之前正在最终确定该声明。在关闭数据库之前完成语句时,将完成最终化。
  4. 您不知道错误代码,因为您没有从sqlite3_step存储它,这是一个int。
  5. 您将提前从方法返回而不关闭数据库。你应该设置一个成功标志,然后确保你的数据库实际打开,然后关闭它然后在结尾处返回标志。

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

}
© www.soinside.com 2019 - 2024. All rights reserved.