简体   繁体   中英

Insert data into sqlite database

I'm insert data into sqlite database and I've seen NSLog(@"DONE") on my console result, but I don't see the data update in my sqlite database file. Pls help me !!!

Here my code to save data:

- (void)saveData:(NSString *)_Id
{
    sqlite3_stmt    *statement;
    NSString *_databasePath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"data.db"];

    const char *dbpath = [_databasePath UTF8String];

    if (sqlite3_open(dbpath, &db) == SQLITE_OK)
    {

        NSString *insertSQL = [NSString stringWithFormat:
                               @"INSERT INTO MyTable (id) VALUES (\"%@\")", _Id];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(db, insert_stmt,
                           -1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            NSLog(@"DONE");
        } else {
            NSLog(@"Failed to add contact");
        }
        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
}

You are opening the database in your bundle. The bundle is read-only on the device. You must copy the database to your Documents folder (if it doesn't exist there already) and open it from there.

Also be aware that you're dealing with multiple copies of the database (the one in your project, the one in the bundle and now the one in the device/simulator's Documents folder). Make sure you're checking for the inserted record in the correct database (the one in Documents )

As an aside, you should also check to see that sqlite3_prepare_v2 returned SQLITE_OK and if not, log sqlite3_errmsg .

You should also use ? placeholder in your SQL and bind values using sqlite3_bind_text (or, if it's possibly nil , sqlite_bind_null ):

- (void)saveData:(NSString *)_Id
{
    sqlite3_stmt    *statement;
    NSString *bundlePath = [[[NSBundle mainBundle] resourcePath ] stringByAppendingPathComponent:@"data.db"];
    NSString *documentsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *documentsPath = [documentsFolder stringByAppendingPathComponent:@"data.db"];
    NSFileManager *fileManager = [NSFileManager defaultManager];

    if (![fileManager fileExistsAtPath:documentsPath isDirectory:NO]) {
        NSError *error;
        if (![fileManager copyItemAtPath:bundlePath toPath:documentsPath error:&error]) {
            NSLog(@"database copy failed: %@", error);
        }
    }

    const char *dbpath = [documentsPath UTF8String];

    if (sqlite3_open(dbpath, &db) == SQLITE_OK) {
        const char *insertSql = "INSERT INTO MyTable (id) VALUES (?)";
        if (sqlite3_prepare_v2(db, insertSql, -1, &statement, NULL) != SQLITE_OK) {
            NSLog(@"prepare error: %s", sqlite3_errmsg(db));
        }

        // bind a value to the ? placeholder in the SQL

        if (_Id) {
            if (sqlite3_bind_text(statement, 1, [_Id UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK) {
                NSLog(@"bind text error: %s", sqlite3_errmsg(db));
            }
        } else {
            if (sqlite3_bind_null(statement, 1) != SQLITE_OK) {
                NSLog(@"bind null error: %s", sqlite3_errmsg(db));
            }
        }

        if (sqlite3_step(statement) == SQLITE_DONE) {
            NSLog(@"DONE");
        } else {
            NSLog(@"Failed to add contact: %s", sqlite3_errmsg(db));
        }

        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
}

Most people move that "if database doesn't exist in documents, then copy it from the bundle and open it from there" logic inside a dedicated openDatabase method, but hopefully this illustrates the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM