Reputation:
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);
}
}
Upvotes: 0
Views: 1804
Reputation: 318794
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.
Upvotes: 2
Reputation: 1607
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];
Upvotes: 0