SQLite bulk insert on iPhone not working
I have been struggling with this seeminly easy problem for 48 hours, and I am no closer to a solution. So I was hoping that someone might be able to help me.
I am building a app, that use a combination of a local (SQLite) database and an online database (PHP/MYSQL). The app is nearly finished. Checked for leaks and work like a charm. However the very last part is the part I have struggled with.
On launch, I want the app to check for changes to the online databse, and if there is. I want it to download and parse a xml file containing the changes. Everything is working fine this far. But when I try to bulk insert my parsed data to my database, the app crashes, giving a NSInternalInconsistency error. Due to the database returning SQLITE_MISUSE. I have done a lot of googling, but am still unable to solve my problem. So I am putting the code here, hoping that someone can help me fix this.
And I know that I should have used core data for this. But this is the very last part I am struggling with, and I am very reluctant to changing my entire code now. Core data will have to come in the update.
Here is the error I recieve:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while inserting data. 'library routine called out of sequence''
Here is my code:
-(void)UpdateDatabase:(const char *)_query NewValues:(NSMutableArray *)_odb dbn:(NSString *)_dbn dbp:(NSString *)_dbp
{
sqlite3 *database;
NSMutableArray *NewValues = _odb;
int i;
const char *query = _query;
sqlite3_stmt *addStmt;
for (i = 1; i < [NewValues count]; i++)
{
if(sqlite3_prepare_v2(database, query, -1, &addStmt, NULL) == SQLITE_OK)
{
sqlite3_bind_text(addStmt, 1, [[[NewValues objectAtIndex:i] name] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [[[NewValues objectAtIndex:i] city]UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_double(addStmt, 3, [[[NewValues objectAtIndex:i] lat] doubleValue]);
sqlite3_bind_int(addStmt, 4, [[[NewValues objectAtIndex:i] long] doubleValue]);
sqlite3_bind_int(addStmt, 5, [[[NewValues objectAtIndex:i] code] intValue]);
}
if(SQLITE_DONE != sqlite3_step(addStmt)) {
NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(databa开发者_StackOverflowse));
}
//Reset the add statement.
sqlite3_reset(addStmt);
}
}
I stumbled upon this while searching for something else. I assume App_beginner finally noticed that he was never opening the database before trying to use it.
sqlite3_open([dbPath UTF8String], &database);
Just thought I'd post (what appears to be the answer) for others
One thing that I notice in your code is that you query parameter #4 is bound to an int while you ask the object for it's doubleValue
.
Also, are you sure the input objects are ok? You might want to add some assertions to make sure none of its fields are nil.
I believe I just solved the same problem. The solution is to call:
sqlite3_reset(insert_statement);
between your insert iterations (at the end of each iteration) in your for loop.
精彩评论