Where should close sqlite connection - iOS App - ios

My iOS app is terminating on the line
sqlite3_exec(database, "COMMIT", 0, 0, 0);
Following is the complete function.
-(void)clearCarts
{
sqlite3_exec(database, "BEGIN", 0, 0, 0);
sqlite3_stmt *stmt = nil;
const char *sql = "DELETE FROM carts";
if(sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error:'%s'", sqlite3_errmsg(database));
if (SQLITE_DONE != sqlite3_step(stmt))
NSAssert1(0, #"Error:'%s'", sqlite3_errmsg(database));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
sqlite3_exec(database, "COMMIT", 0, 0, 0);// terminates here
}
What could be the reason and where should I use sqlite3_close(database) as sqlite3_close(database) is not being used in any function.
Please suggest, thank you in advanced.

This must be because you are not opening your database to execute the query and you should use sqlite3_close(database) after executing the statement.
Try with below code
sqlite3 *database;
sqlite3_stmt *selectstmt;
if (sqlite3_open([yourDatabasePath UTF8String], &database) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"DELETE FROM carts"];
const char *insert_stmt = [sql UTF8String];
sqlite3_prepare_v2(database,insert_stmt, -1, &selectstmt, NULL);
if(sqlite3_step(selectstmt)==SQLITE_DONE)
{
NSLog(#"Delete successfully");
}
else
{
NSLog(#"Error while Clean Database. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(selectstmt);
}
sqlite3_close(database);

Related

Update not working sqlite in objective c

I am trying to update row in a loop and its not working. I have explained the scenario below
I have got set of values from web services stored in arrays. Now i have to update those values in DB by looping through the array. Below is the code am using:
NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"db_name" ofType:#"sqlite"];
sqlite3 *database;
sqlite3 *database1;
sqlite3_open([dbPath UTF8String], &database1);
sqlite3_open([dbPath UTF8String], &database);
NSInteger loopCnt = 0;
NSString *s = [[NSString alloc] init];
const char *sql;
sqlite3_stmt *selectstmt;
NSString *q = [[NSString alloc] init];
for(NSString *itemId in itemIds)
{
s = [NSString stringWithFormat:#"SELECT * from table where id=%#", itemId];
sql = [s UTF8String];
int result = sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL);
if(result == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
if ((char *)sqlite3_column_text(selectstmt, 0) != NULL)
{
rowNumVal = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
col1 = [values1 objectAtIndex:loopCnt];
col2 = [values2 objectAtIndex:loopCnt];
if([rowNumVal integerValue] > 0)
{
q = [NSString stringWithFormat:#"UPDATE table set col1=?, col2=? WHERE id=?"];
}
}
}
}
sqlite3_finalize(selectstmt);
sqlite3_exec(database1, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
sqlite3_stmt *stmt;
const char *query = [q UTF8String];
if(sqlite3_prepare_v2(database1, query, -1, &stmt, NULL)== SQLITE_OK)
{
if(sqlite3_bind_text(stmt, 1, [col1 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 1 %s", sqlite3_errmsg(database1));
}
if(sqlite3_bind_text(stmt, 2, [col2 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 2 %s", sqlite3_errmsg(database1));
}
if (sqlite3_step(stmt) != SQLITE_DONE){
NSLog(#"Delete commit failed. Error %s", sqlite3_errmsg(database1));
}
if(sqlite3_reset(stmt)!= SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
}
sqlite3_trace(database1, sqliteCallbackFunc, NULL);
sqlite3_finalize(stmt);
if(sqlite3_exec(database1, "COMMIT TRANSACTION", 0, 0, 0) != SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
loopCnt++;
}
sqlite3_close(database);
sqlite3_close(database1);
I am fetching the values using id to check row exists and if exists am updating. Everything logs and runs fine but still DB is not getting updated.
Please let me know where is the issue.
You need to call:
sqlite3_finalize(stmt);
Before:
if(sqlite3_reset(stmt)!= SQLITE_OK)
{
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
In current code, you are resetting the prepared SQLite statement to it's initial state before finalizing it.
Another issue is, you are trying to update the database that is located in App Bundle. It won't work, because app bundle is read-only. You need to copy the database to document directory and do the operations on that copied database.

getting error in sqlite Update in ios

i am getting error in the sqlite updation,here the query is correctly given, but the value is not updating.here i need to update the description value Where the given place, Below i add my code please help me
-(void) update:(NSString *)filePath withName:(NSString *)place description:(NSString*)description
{
sqlite3* db = NULL;
int rc=0;
sqlite3_stmt* stmt =NULL;
rc = sqlite3_open_v2([filePath cStringUsingEncoding:NSUTF8StringEncoding], &db, SQLITE_OPEN_READWRITE , NULL);
if (SQLITE_OK != rc)
{
sqlite3_close(db);
NSLog(#"Failed to open db connection");
}
else
{
NSString * query = [NSString stringWithFormat:#"UPDATE places SET description=%# WHERE place=%#",description,place];
sqlite3_bind_text(stmt, 1, [place UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [description UTF8String], -1, SQLITE_TRANSIENT);
NSLog(#"query %#",query);
char * errMsg;
rc = sqlite3_exec(db, [query UTF8String] ,NULL,&stmt,&errMsg);
if(SQLITE_OK != rc)
{
NSLog(#"Failed to insert record rc:%d, msg=%s",rc,errMsg);
}
else{
NSLog(#"Sucessfully updated");
}
sqlite3_finalize(stmt);
sqlite3_close(db);
}
}
Table Creation
-(int) createTable:(NSString*) filePath
{
sqlite3* db = NULL;
int rc=0;
NSLog(#"create");
rc = sqlite3_open_v2([filePath cStringUsingEncoding:NSUTF8StringEncoding], &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (SQLITE_OK != rc)
{
sqlite3_close(db);
NSLog(#"Failed to open db connection");
}
else
{
char * query ="CREATE TABLE IF NOT EXISTS places ( id INTEGER PRIMARY KEY AUTOINCREMENT,place TEXT ,locationname TEXT,time TEXT,description TEXT,notifyTime TEXT,radius TEXT,lat DOUBLE,lon DOUBLE ,notify TEXT,selection INTEGER)";
char * errMsg;
rc = sqlite3_exec(db, query,NULL,NULL,&errMsg);
if(SQLITE_OK != rc)
{
NSLog(#"Failed to create table rc:%d, msg=%s",rc,errMsg);
}
else{
NSLog(#"Sucessfully Created ");
}
sqlite3_close(db);
}
return rc;
}
First open the DB connection.
Then write below code.
NSString * query = [NSString stringWithFormat:#"UPDATE places SET description=%# WHERE place=%#",description,place];
SQL=[NSString stringWithString:query];
sqlite3_stmt *insert_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &insert_statement, NULL) != SQLITE_OK) {
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
NSLog(#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
int result=sqlite3_step(insert_statement);
sqlite3_finalize(insert_statement);
and then close the DB connection
try this ...check db is whether it is opened or not and change this code...
-(void) update:(NSString *)filePath withName:(NSString *)place description:(NSString*)description
{
sqlite3* db = NULL;
int rc=0;
sqlite3_stmt* stmt =NULL;
rc = sqlite3_open_v2([filePath cStringUsingEncoding:NSUTF8StringEncoding], &db, SQLITE_OPEN_READWRITE , NULL);
if (SQLITE_OK != rc)
{
sqlite3_close(db);
NSLog(#"Failed to open db connection");
}
else
{
/*
NSString *strMQueryupdate=[NSString stringWithFormat:#"update br set TOTAL='%#',QUTY='%#' WHERE PID='%#'",[#(total )stringValue],[#(lblQtn )stringValue],produdId];
*/
NSString * query = [NSString stringWithFormat:#"UPDATE places SET description='%#' WHERE place='%#'",description,place];
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(db, sql, -1, & stmt, NULL) != SQLITE_OK)
{
NSLog(#"update fails");
}
else
{
sqlite3_bind_text(stmt, 1, [place UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [description UTF8String], -1, SQLITE_TRANSIENT);
int success = sqlite3_step(stmt);
sqlite3_reset(stmt);
if (success == SQLITE_ERROR)
{
}
else
{
NSLog(#"update success");
}
sqlite3_finalize(update_statement);
sqlite3_close(db);
}
}
You're using prepared statements incorrectly. You hard-code the values in a string (a bad idea) and then setting the placeholder values -- which makes no sense as there are no placeholders in your SQL. Try something like:
NSString * query = #"UPDATE places SET description= ? WHERE place= ?";
sqlite3_bind_text(stmt, 1, [place UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [description UTF8String], -1, SQLITE_TRANSIENT);
The reason you don't want to include the values directly in the query string: imagine someone passing in a value for place like "London'; drop table places;". (Not sure if that'll work but it should give you some idea of the kind of mischief that a user could get up to.)

SQLITE update table issue

I am new to Sqlite and I am working on an application which uses Sqlite.
I have succeeded in creation of table and inserting values into it.
I am trying to update the table but the table is not getting updated.
Below is the code for updating a table:
-(BOOL)updateData:(NSString *)screenName status:(NSString *)currentStatus{
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open (dbPath, &database) == SQLITE_OK) {
NSString *updateSQL = [NSString stringWithFormat:#"Update productDetail Set status = \"%#\" where current_screen = \"%#\"",currentStatus,screenName];
// const char *update_stmt = "update productDetail Set status = ? Where screenName=?";
const char *update_stmt = [updateSQL UTF8String];
/*
if (sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL)) {
sqlite3_bind_text(statement, 0, [currentStatus UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [screenName UTF8String], -1, SQLITE_TRANSIENT);
}
*/
/*
char* errmsg;
sqlite3_exec(database, "COMMIT", NULL, NULL, &errmsg);
*/
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL);
/*
sqlite3_bind_text(statement, 1, [currentStatus UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [screenName UTF8String], -1, SQLITE_TRANSIENT);
*/
if (sqlite3_step(statement) == SQLITE_OK) {
NSLog(#"Updated Successfully!!");
return YES;
}
else{
NSLog(#"error: %s",sqlite3_errmsg(database));
NSLog(#"Failed Updated");
}
int result=sqlite3_bind_text(statement, 1, Nil , -1, SQLITE_TRANSIENT);
NSLog(#"bind result= %i", result);
if(sqlite3_step(statement) != SQLITE_DONE) {
NSLog(#"Problems updating");
NSLog(#"error: %s",sqlite3_errmsg(database));
return NO;
}
else{
NSLog(#"Updated");
}
sqlite3_finalize(statement);
}
return YES;
}
Please let me know what I am doing wrong.
Thanks
ERROR:
Failed Updated
bind result= 21
Problems updating
rror: library routine called out of sequence
You have too much commented-out code, and the remaining code is garbled as a result.
Your code tries to bind a parameter, but your current query does not use parameters.
Furthermore, the return value of sqlite3_step can never be SQLITE_OK, and you are trying to execute the query twice (and the database complains because you did not call sqlite3_reset).
Use this code:
result = NO;
const char *update_stmt = "UPDATE productDetail SET status=? WHERE screenName=?";
if (sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL) != SQLITE_OK) {
NSLog(#"prepare error: %s", sqlite3_errmsg(database));
} else {
sqlite3_bind_text(statement, 1, [currentStatus UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [screenName UTF8String], -1, SQLITE_TRANSIENT);
if (sqlite3_step(statement) != SQLITE_DONE)
NSLog(#"execution error: %s", sqlite3_errmsg(database));
else
result = YES;
sqlite3_finalize(statement);
}
return result;

xCode iOS SQLite not working update

Help, not working UPDATE in SQite. query is executed but the changes do not occur
const char *dbPath=[databasePath UTF8String];
if (sqlite3_open(dbPath, &contactDB)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update poi set test=\"111\"";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(contactDB, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Executed");
}
}
sqlite3_close(contactDB);
you made minor mistake....
Write ur stuff in following template, you missed the main execution statement i.e.
sqlite3_step(statement);
What is happening here, you are just preparing the statement and not executing it..
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &database_object) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"update table_name set column_name = \"%#\"", Your_value];
const char *sql_stmt = [sql UTF8String];
if(sqlite3_prepare_v2(database_object , sql_stmt, -1, &statement, NULL) != SQLITE_OK)
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(database_object));
if(SQLITE_DONE != sqlite3_step(statement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database_object));
sqlite3_finalize(statement);
}
Make these changes in your code and try, i think it will work...
You haven't executing the Query :
sqlite3_prepare_v2- Just prepared not to execute(affect) , You need to execute it
Try this Out:
const char *dbPath=[databasePath UTF8String];
if (sqlite3_open(dbPath, &contactDB)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update poi set test=\"111\"";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(contactDB, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Prepared to execute");
}
if(sqlite3_step(stmt) != SQLITE_DONE){
NSAssert1(0, #"Error while updating. '%s'", sqlite3_errmsg(database));
}else
NSLog(#"Executed");
sqlite3_close(contactDB);
}

sqlite many opens one fail

I have sqlite database in iPhone app and there I store questions.
I get one question, user answers YES or NO, result is showing on second viewController and when second viewController is closing I get another question.
Everything works perfectly and suddenly after 30-40 questions, program cannot open database.
if(sqlite3_open([DBPath UTF8String], &database) == SQLITE_OK) - it fails.
Any answers?
This function:
// get Question from Database
- (void)getQuestion:(int)getQ
{
NSLog(#"getQuestion Started");
sqlite3 *database;
sqlite3_stmt *compiledStatement = NULL;
if(sqlite3_open([DBPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sqlite opened");
const char *sql = "Select QuestionID, Question from cQuestions WHERE ExerciseLinID = ? ORDER BY QuestionID LIMIT ?, 1";
if(sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating detail view statement. '%s'", sqlite3_errmsg(database));
int curExID = [[listOfExID objectAtIndex:ExSel] integerValue];
sqlite3_bind_int(compiledStatement, 1, curExID);
sqlite3_bind_int(compiledStatement, 2, getQ);
if(SQLITE_DONE != sqlite3_step(compiledStatement))
{
NSLog(#"Got one record");
selectedQues = sqlite3_column_int(compiledStatement, 0);
NSLog(#"selectedQues = %i", selectedQues);
const char *QuNam = (char *)sqlite3_column_text(compiledStatement, 1);
if(QuNam == nil)
NSLog(#"!!! No data found.");
else
{
if( iWhat == YES )
_labQuestion.text = [[NSString alloc] initWithCString:QuNam encoding:NSASCIIStringEncoding];
else
_labQuestionPad.text = [[NSString alloc] initWithCString:QuNam encoding:NSASCIIStringEncoding];
}
}
}
else
{
NSLog(#"!!! Open error. %s", sqlite3_errmsg(database));
NSLog(#"!!! Open error. %d", sqlite3_errcode(database));
}
sqlite3_close(database);
}
Add some NSLog to understand which is the error.
if(sqlite3_open([DBPath UTF8String], &database) == SQLITE_OK) {
// Your Code
}
else {
NSLog(#"sqlite3_open failed. Error:%d. %s", sqlite3_errcode(database), sqlite3_errmsg(database));
}
One potential problem is the fact that you aren't closing your database, are you closing it?
sqlite3_close(database);

Resources