在使用sqlite3进入db iPhone时插入数据期间出现问题

时间:2012-12-05 17:09:19

标签: iphone objective-c ios xcode sqlite

我有一个问题,我试图将NSMutableArra y中的数据插入到我的数据库中。以下是我到目前为止的情况:

- (void)insertList:(NSString*) strListName ArrayOfData:(NSMutableArray*) dataArray{
sqlite3 *database = nil;
sqlite3_stmt *addStmt = nil;

NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"customlists.sqlite"];
if(sqlite3_open([defaultDBPath UTF8String], &database) == SQLITE_OK)
{
    for (int i = 0; i < dataArray.count; i++)
    {
        PageData *pageDta = [PageData new];
        pageDta = [dataArray objectAtIndex:i];

        if(addStmt == nil) {
            const char *sql = "insert into NewList(ListName, PageName, PageNumber, id) Values(?, ?, ?, ?)";
            if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
                NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
        }

        sqlite3_bind_text(addStmt, 1, [strListName UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 2, [pageDta.strNamebyFilter UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 3, [pageDta.strPageNuber UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_int(addStmt, 4, i);

        if(SQLITE_DONE != sqlite3_step(addStmt))
            NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
        else
            //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
            sqlite3_last_insert_rowid(database);

        //Reset the add statement.
        sqlite3_reset(addStmt);
    }
}
else
{
    NSLog(@"Error while opening database '%s'", sqlite3_errmsg(database));
}
sqlite3_close(database);
}

但是在调用此函数后,数据库为空。有人可以帮助我找到这个问题的原因和潜在的补救措施吗?

3 个答案:

答案 0 :(得分:1)

主要问题很简单 - 您正在尝试写入应用程序包中的数据库。这是不允许的。应用程序包在真实设备上是只读的(尽管它在模拟器中是可写的)。正确的做法是在应用程序第一次运行时将数据库从资源包复制到应用程序沙箱的可写区域。然后,使用副本完成数据库的每次使用。

for循环之前准备语句也会更清晰。无需继续检查是否每次循环迭代都设置了它。

您拨打sqlite3_last_insert_rowid但未对该值执行任何操作。有什么意义?

循环完成后,您永远不会完成语句。你需要这样做。

完成后不要关闭数据库。

答案 1 :(得分:0)

更改此行:

const char *sql = "insert into NewList(ListName, PageName, PageNumber, id) Values(?, ?, ?, ?)";

到:

NSString *insertSQL = [NSString stringWithFormat: @"NSString stringWithFormat: "INSERT INTO  NewList(ListName, PageName, PageNumber, id) VALUES(\"%@\", \"%@\", \"%@\", \"%@\")" ,strListName, pageDta.strNamebyFilter, pageDta.strPageNuber, addStmt];

const char *sql = [insertSQL UTF8String];

答案 2 :(得分:-1)

我已将功能重写为:

 if(sqlite3_open([defaultDBPath UTF8String], &database) == SQLITE_OK)
{
    for (int i = 0; i < dataArray.count; i++)
    {
        PageData *pageDta = [PageData new];
        pageDta = [dataArray objectAtIndex:i];

        if(addStmt == nil) {
            const char *sql = [[NSString stringWithFormat:@"INSERT INTO NewList (ListName, PageName, PageNumber) values('%@', '%@', '%@')",strListName,pageDta.strNamebyFilter, pageDta.strPageNuber] UTF8String];

            if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
                NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
        }

        sqlite3_bind_text(addStmt, 1, [strListName UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 2, [pageDta.strNamebyFilter UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 3, [pageDta.strPageNuber UTF8String], -1, SQLITE_TRANSIENT);

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

        //Reset the add statement.
        sqlite3_reset(addStmt);
    }
    sqlite3_finalize(addStmt);
}
else
{
    NSLog(@"Error while opening database '%s'", sqlite3_errmsg(database));
}
sqlite3_close(database);   

但结果是一样的:(