I have done lot of googling on updating the created sqlite table still i did not able to update my table in my sample app .Can any one please tell me what is wrong with my below code .IT works fine till sqlite3_prepare_v2.Once it reach if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK) condition it is not going into this if() condition can any one tell what is happening here?
const char *dbpath = [[self DBPath] UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySql=[NSString stringWithFormat:#"UPDATE Table1 SET AppEndTime = %# WHERE AppID= %d",AppEndTime,appID];
const char *sql=[querySql UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK){
sqlite3_bind_int(statement, 1, sessionID);
sqlite3_bind_text(statement, 6, [sessionEndTime UTF8String], -1, SQLITE_TRANSIENT);
}
}
char* errmsg;
sqlite3_exec(database, "COMMIT", NULL, NULL, &errmsg);
if(SQLITE_DONE != sqlite3_step(statement)){
NSLog(#"Error while updating. %s", sqlite3_errmsg(database));
}
else{
sqlite3_reset(statement);
}
sqlite3_finalize(statement);
sqlite3_close(database);
Please replace you code as given below.I hope it will solve your problem.
if (sqlite3_prepare_v2(database, sql, -1, &Statement1, NULL) == SQLITE_OK) {
sqlite3_bind_text(Statement1, 1, [status UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(Statement1, 2, [messageID UTF8String], -1, NULL);
int success = sqlite3_step(Statement1);
if(success != SQLITE_ERROR)
{
// NSLog(#"Success");
}
sqlite3_finalize(Statement1);
}
Here is my code which update created table. Have a look hope it'll help you.
-(BOOL)updateMyTable{
BOOL isGood = YES;
#try {
NSString *fName = [user_dic valueForKey:#"fName"];
NSString *lName = [user_dic valueForKey:#"lName"];
NSString *email_id = [user_dic valueForKey:#"email_id"];
NSString *employee_id = [user_dic valueForKey:#"employee_id"];
fName= [fName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
lName= [lName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
email_id= [email_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
employee_id= [employee_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
// NSString *autoId = [user_dic valueForKey:#"autoId"];
NSString *sql = [NSString stringWithFormat:#"UPDATE tbl_profile SET fName = '%#', lName = '%#', email_id = '%#' ,employee_id = '%#' WHERE autoId = '%#'",fName,lName,email_id,employee_id,autoId];
[database executeUpdate:sql,nil];
if (MyDelegate.isLogging) {
NSLog(#"edit user QUERY---- >>>>%#",sql);
NSLog(#"edit user RESULT CODE ---- >>>>%d:", [database lastErrorCode]);
NSLog(#"edit user RESULT ERROR MESSAGE ---- >>>>%#",[database lastErrorMessage]);
}
}#catch (NSException *exception) {
isGood = NO;
}
#finally {
}
return isGood;
Please make sure your Sqlite file is in the documents directory,Not in project folder.
Update and insert will work if and only if the file is in the document directory
see this answer
Related
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.
Code:
#try {
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
const char * sql="Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%%%#%%'";
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [searchWord UTF8String], -1, SQLITE_TRANSIENT);
while (sqlite3_step(statement) ==SQLITE_ROW)
{
}
}
else
NSAssert1(0, #"Error in candidateinfo. '%s'", sqlite3_errmsg(database));
sqlite3_reset(statement);
}
}#catch (NSException * e) {
NSLog(#"Exception is %#, %#", [e name], [e reason]);
}#finally {
sqlite3_finalize(statement);
sqlite3_close(database);
}
I try to fetch data from sqlite based on search keyword.I tried with like statement.The query is not executing and is goes out of while loop.what is wrong with my code.thanks in advance
Try creating your Query using NSString :
NSString *sql = [NSString stringWithFormat:#"Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%#'", searchWord] ;
if (sqlite3_prepare_v2(database, [sql cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK)
{
}
Problem is that you are using 'sqlite3_bind_text' in wrong way.
Your query must be :
const char * sql="Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%%?%%'";
You are missing '?'
I found answer to my question
NSString *query = [NSString stringWithFormat:#"Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation LIKE '%%%#%%'", searchWord];
const char *sql = [query UTF8String];
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.)
In the code below, the commented-out code works.
But using the saveData method of the DBMgr Class results in "Failded to add contact".
I want to see "Contact added" instead.
-(void) saveData{
NSString *insSQL = [NSString stringWithFormat:#"INSERT INTO CONTACTS (name,address,phone) VALUES (\"%#\",\"%#\",\"%#\")",name.text,address.text,phone.text];
DBMgr *dbmgr = [DBMgr alloc];
if([dbmgr saveData:insSQL]== 0){
status.text = #"Contact added";
}else if([dbmgr saveData:insSQL]== 1){
status.text=#"Failded to add contact";
}
/*sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:#"INSERT INTO CONTACTS (name,address,phone) VALUES (\"%#\",\"%#\",\"%#\")",name.text,address.text,phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_DONE)
{
status.text = #"Contact added";
name.text = #"";
address.text = #"";
phone.text = #"";
}else{
status.text=#"Failded to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}*/
}
-(NSInteger) saveData:(NSString *) querySQL{
NSInteger result;
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = querySQL;
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_DONE)
{
result = 0;
}else{
result = 1;
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
return result;
}
You should check the result codes of all of your SQLite calls, and if they fail, log the error:
- (NSInteger) saveData:(NSString *) querySQL{
NSInteger result = 1;
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = querySQL;
const char *insert_stmt = [insertSQL UTF8String];
if (sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK)
NSLog(#"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(contactDB));
else
{
if(sqlite3_step(statement) == SQLITE_DONE)
{
result = 0;
}else{
NSLog(#"%s: step failed: %s", __FUNCTION__, sqlite3_errmsg(contactDB));
}
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
} else {
NSLog(#"%s: open failed", __FUNCTION__);
}
return result;
}
Unless you look at sqlite3_errmsg, you're just guessing. And check sqlite3_prepare_v2 return code, too, like I did above, (as that will more likely be the initial indication of a problem).
Two other, unrelated, observations:
The DBMgr should be initialized, e.g.:
DBMgr *dbmgr = [[DBMgr alloc] init];
You are building your INSERT statement using stringWithFormat. That's very dangerous, you should use ? placeholders in your SQL:
const char *insSQL = "INSERT INTO CONTACTS (name,address,phone) VALUES (?, ?, ?)";
sqlite3_prepare_v2(contactDB, insSQL, -1, &statement, NULL);
Then, after preparing that statement, you should then use the sqlite3_bind_text function to assign your values to those three placeholders, e.g.
sqlite3_bind_text(statement, 1, [name.text UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [address.text UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [phone.text UTF8String], -1, SQLITE_TRANSIENT);
By the way, if you wanted to specify NULL, you'd call sqlite3_bind_null instead of sqlite3_bind_text.
Obviously, check the return code from each of those to make sure you returned SQLITE_OK for each, again, logging sqlite3_errmsg if it failed.
I appreciate that this change is going to require some refactoring of your code, but it's important to use sqlite3_bind_text to avoid SQL injection attacks and errors that will result if the user typed in a value that included quotation marks.
By the way, if you're looking at the above and realizing that it takes a lot of code to do this properly, you might want to consider using FMDB which can significantly simplify your life.
I am trying to update my sqlite database but this code is not working for me.
Please help me to find what is wrong with this.
-(BOOL)StoreFavourite:(NSString*)fav :(int)DuaId
{
NSString* mydbpath=[self pathfinder];
const char *dbpath=[mydbpath UTF8String];
if(sqlite3_open(dbpath,&database )==SQLITE_OK)
{
NSString *query = [NSString stringWithFormat:#"UPDATE Dua SET
favourite=\'%#\' WHERE dua_id=%d ",fav,DuaId];
const char *query_statement=[query UTF8String];
if(sqlite3_prepare_v2(database, query_statement, -1, &statement, NULL)==SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_DONE)
{
return YES;
}
sqlite3_finalize(statement);
}
}
return YES;
}
Please check your "mydbpath" by putting NSLog.I think you have given incorrect path.
Also try to use:
NSString *query = [NSString stringWithFormat:#"UPDATE Dua SET favourite='%#' WHERE dua_id=%d ",fav,DuaId];
here are some reason for due to which the sqlite3_prepare_v2 != SQLITE_OK :
1.The table may not present into the database.
2.Wrong query statement .
3.Wrong column name into the query statement.
You can find the exact problem using error statement by putting following in else:
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database))
please try in following manner
-(BOOL)StoreFavourite:(NSString*)fav :(int)DuaId
{
sqlite3_stmt *statement=nil;
NSString *mydbpath=[self pathfinder];
NSString *query;
if(sqlite3_open([mydbpath UTF8String],&database) == SQLITE_OK)
{
query = [NSString stringWithFormat: #"update Dua set favourite=? where dua_id=?"];
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL)
== SQLITE_OK)
{
sqlite3_bind_int(statement, 2, DuaId);
sqlite3_bind_text(statement, 1, [fav UTF8String], -1, SQLITE_TRANSIENT);
if(sqlite3_step(statement))
{
return YES;
}
else
{
return NO;
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}