简体   繁体   中英

How do I insert string to sqlite in Objective-C?

I could not insert NSMutableString to sqlite. I get the information successfully from web server and create the sqlite file successfully but I could not insert the data from web to sqlite.

I think the problem is here.

NSString *insertSQL = @"INSERT INTO Questions VALUES (result)";

but I am not sure and I could not solve this problem. Could anyone help me please?

- (void)getInforamtionFromWeb {
    NSURL *url = [NSURL URLWithString:kGetUrl];
    data = [NSData dataWithContentsOfURL:url];
    NSError *error;
    json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    result = [[NSMutableString alloc] init];
    for (NSObject * obj in json)
    {
        [result appendString:[obj description]];
    }
}

-(void)initiatSqlite{
    // Get the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = dirPaths[0];
    // Build the path to the database file
    _databasePath = [[NSString alloc]
                     initWithString: [docsDir stringByAppendingPathComponent:
                                      @"Questions.db"]];
    NSFileManager *filemgr = [NSFileManager defaultManager];
    if ([filemgr fileExistsAtPath: _databasePath ] == NO)
    {
        const char *dbpath = [_databasePath UTF8String];
        if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
        {
            char *errMsg;
            const char *sql_stmt =
            "CREATE TABLE IF NOT EXISTS Questions (ID INTEGER PRIMARY KEY AUTOINCREMENT, Question Text, AnswerA Text, AnswerB Text, AnswerC Text, AnswerD Text, CorrectAnswer Text, Explanation Text)";
            if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
            {
                [self Worningtitle:@"Error" Message:@"Failed to create table"];
            }
            sqlite3_close(_contactDB);
        } else {
            [self Worningtitle:@"Error" Message:@"Failed to open/create database"];

        }
    }

}
- (void) insertData
{
    sqlite3_stmt    *statement;
    const char *dbpath = [_databasePath UTF8String];


    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
    {
        NSString *insertSQL = @"INSERT INTO Questions VALUES (result)";

        const char *insert_stmt = [insertSQL UTF8String];
        NSLog(@"%s",insert_stmt);
        sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL);
        sqlite3_bind_text(statement, 1, [result UTF8String], -1, SQLITE_TRANSIENT);

        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            NSLog(@"Product added");
        } else {
            NSLog(@"Failed to add Product");
        }

        sqlite3_finalize(statement);
        sqlite3_close(_contactDB);
    }
}

You are correct. Your INSERT statement is incorrect. It needs to be:

NSString *insertSQL = @"INSERT INTO Questions VALUES (?)";

The ? is where the sqlite3_bind_xxx will be applied.

Keep in mind that your Questions table has lots of columns but you are only inserting a single value. You should specify which column the value should be inserted into. Example:

NSString *insertSQL = @"INSERT INTO Questions (Question) VALUES (?)";

Replace Question with the proper column name that your result value should be put in.

BTW - your code needs a lot more work to make it better. You need to add a lot more error checking, especially with sqlite3_prepare_v2 .

Based on wanting to insert more data, you would do something like this:

- (BOOL)insertData {
    BOOL result = NO; // failed
    const char *dbpath = [_databasePath UTF8String];
    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) {
        const char *insert_stmt = "INSERT INTO Questions(AnswerA,AnswerB,AnswerC,AnswerD,CorrectAnswer,Question) VALUES (?,?,?,?,?,?)";
        sqlite3_stmt *statement;

        if (sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK) {
            sqlite3_bind_text(statement, 1, [answerA UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(statement, 2, [answerB UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(statement, 3, [answerC UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(statement, 4, [answerD UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(statement, 5, [correctAnswer UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(statement, 6, [question UTF8String], -1, SQLITE_TRANSIENT);

            if (sqlite3_step(statement) == SQLITE_DONE) {
                NSLog(@"Product added");
                result = YES;
            } else {
                NSLog(@"Failed to add Product: %s", sqlite3_errmsg(_contactDB));
            }

            sqlite3_finalize(statement);
        } else {
            NSLog(@"Unable to prepare statement: %s", sqlite3_errmsg(_contactDB);
        }

        sqlite3_close(_contactDB);
    } else {
        NSLog(@"Unable to open database: %@", sqlite3_errmsg(_contactDB));
    }

    return result;
}

Please note that you need to update each of the sqlite3_bind_text calls with references to the actual variables/values that contain the data for each column.

You also don't need to bind a value for ID since it is setup to automatically populate.

Note all of the proper error checking. I also made it so insertData returns a BOOL indicating whether the data was successfully added or not.

Hear make common method for all table :

+(BOOL)insertWithReturnConfirmInTable:(NSString *)tableName Param:(NSDictionary *)params
{
        NSArray *keys = [[NSArray alloc] initWithArray:[self GetColumnsForTable:tableName]];

        //insert statement
        NSString *query = [NSString stringWithFormat:@"INSERT INTO %@(",tableName];

        //set keys
        for (int i=0; i<[keys count]; i++) {
            if([keys objectAtIndex:i] == [keys lastObject])
            {
                query = [query stringByAppendingString:[NSString stringWithFormat:@"%@) VALUES (",[keys objectAtIndex:i]]];
                for (int m=0; m<[keys count]; m++) {

                    if([keys objectAtIndex:m] == [keys lastObject])
                        query = [query stringByAppendingString:@"?)"];
                    else
                        query = [query stringByAppendingString:@"?,"];
                }
            }
            else
            {
                query = [query stringByAppendingString:[NSString stringWithFormat:@"%@,",[keys objectAtIndex:i]]];
            }
        }
        NSLog(@"Query : %@",query);

        if (sqlite3_open([[self getDBPath] UTF8String], &dbObj) == SQLITE_OK) {

            sqlite3_stmt *addStmt = nil;

            if (sqlite3_prepare_v2(dbObj, [query UTF8String], -1, &addStmt, NULL) != SQLITE_OK)
                NSAssert1(0, @"Error while creating insert statement. '%s'",sqlite3_errmsg(dbObj));

            //for Values
            for (int i=0; i<[keys count]; i++) {
                sqlite3_bind_text(addStmt, i+1, [[NSString stringWithFormat:@"%@",[params objectForKey:[keys objectAtIndex:i]]] UTF8String], -1, SQLITE_TRANSIENT);
            }

            if (SQLITE_DONE != sqlite3_step(addStmt)) {
                NSLog(@"Error while inserting data. '%s'", sqlite3_errmsg(dbObj));
                sqlite3_close(dbObj);
                return NO;
            }
            else {
                sqlite3_finalize(addStmt);
                NSLog(@"data inserted in table : %@",tableName);
                sqlite3_close(dbObj);
                return YES;
            }


        } else {
            NSLog(@"Error in opening database.");
            sqlite3_close(dbObj);
            return NO;
        }

    }
}

Call method : Pass all field name as key and all value as value in dictionary. and pass table name.

NSDictionary *param = [[NSDictionary alloc]initWithObjectsAndKeys:@"1",@"S_Id",@"abc",@"Name", nil];
[database insertInTable:@"Child" Param:param];

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