I am trying to update one of my table's column upon button click.
The issue is that code isn't giving any exception still it is not updating the table.
When the view controller load again , it shows the old value rather then updated one.
Code for update db is attached below.
#try {
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *sqlStatement = #"UPDATE messagesTable SET Favorite = 1 where MessageID=";
sqlStatement = [sqlStatement stringByAppendingString:msgId];
NSLog(#"sql statement: %#", sqlStatement);
const char *sql = [sqlStatement UTF8String];
int result = sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL);
if(result != SQLITE_OK) {
NSLog(#"Prepare-error #%i: %s", result, sqlite3_errmsg(database));
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
#catch (NSException *exception) {
NSLog(#"Name: %#",exception.name);
NSLog(#"Reason: %#",exception.reason);
}
#finally {
}
Any suggestions are welcome. :-)
You are not calling sqlite3_step, which performs the update. After the sqlite3_prepare and before the sqlite3_finalize, you need something like:
if (sqlite3_step(compiledStatement) != SQLITE_DONE)
NSLog(#"%s: step error: %s", __FUNCTION__, sqlite3_errmsg(database));
Related
Using For in loop inserting or updating table using SQlite query ,it's throw updating correctly message and also Error while updating. 'unknown error' error msg also.Insertion is done correctly but update not worked same if run update query in SQLite Manager it worked..thanks advance
sqlite3 *database;
NSString * databaseName=[[NSString alloc]initWithString:DBName];
NSArray * documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString * databasePath = [[documentsDir stringByAppendingPathComponent:databaseName] retain];
NSString *lite;
BOOL check=[self isContainsID:filename];
if(check)
{
lite=[NSString stringWithFormat:#"INSERT INTO table_name(id,filename,date)VALUES('%#',%d,'%#')",id,filename,date];
}
else
{
lite=[NSString stringWithFormat:#"UPDATE table_name SET date='%#' where filename ='%#'",date,filename];
const char *sqlStatement = [lite UTF8String];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
// Setup the SQL Statement and compile it for faster access
sqlite3_stmt *compiledStatement=nil;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) != SQLITE_OK)
{
if(Debug)
{
DLog(#"not updated");
DLog(#"HMM, COULDNT RUN QUERY: %s\n", sqlite3_errmsg(database));
}
}
else
{
if (sqlite3_step(compiledStatement) == SQLITE_DONE)
{
DLog(#"updated successfully");
}
if(SQLITE_DONE != sqlite3_step(compiledStatement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
[databaseName release];
[databasePath release];
This code is wrong and results in calling sqlite3_step() twice:
if (sqlite3_step(compiledStatement) == SQLITE_DONE)
{
DLog(#"updated successfully");
}
if(SQLITE_DONE != sqlite3_step(compiledStatement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
I'm sure you meant:
if (sqlite3_step(compiledStatement) == SQLITE_DONE)
{
DLog(#"updated successfully");
}
else
{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
Also you should be binding your statement variable instead of formatting them into the statement with [NSString stringWithFormat:], as it's both more secure and allows the statements to be re-used (which is the point of preparing them).
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);
What am i doing wrong here?? i have three table in database, and i need to delete all data from them.
-(void)deleteAllDataFromTables
{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSLog(#"%#", appDelegate.databasePath);
int result = sqlite3_open([appDelegate.databasePath UTF8String], &db);
if(result == SQLITE_OK)
{
NSLog(#"deleteCalled");
const char *deleteData = "delete from CustomerNumberTable";
int outcome = sqlite3_prepare_v2(db, deleteData, -1, &statement, NULL);
if(outcome == SQLITE_OK)
{
int res = sqlite3_step(statement);
if(res == SQLITE_DONE)
{
NSLog(#"deleted from Customer Table");
}
else
{
NSLog(#"not able to execute step statement");
}
}
else
{
NSLog(#"not deleted from Customer Table");
NSLog(#"the error is %s", sqlite3_errmsg(db));
}
sqlite3_finalize(statement);
const char *deleteData2 = "delete from KeyCodeTable";
int outcome2 = sqlite3_prepare_v2(db, deleteData2, -1, &statement, NULL);
if(outcome2 == SQLITE_OK)
{
int res = sqlite3_step(statement);
if(res == SQLITE_DONE)
{
NSLog(#"deleted from KeyCodeTable");
}
else
{
NSLog(#"not able to execute step statement");
}
}
else
{
NSLog(#"not deleted from KeyCodeTable");
NSLog(#"the error is %s", sqlite3_errmsg(db));
}
sqlite3_finalize(statement);
const char *deleteData3 = "delete from SRNumberTable";
int outcome3 = sqlite3_prepare_v2(db, deleteData3, -1, &statement, NULL);
if(outcome3 == SQLITE_OK)
{
int res = sqlite3_step(statement);
if(res == SQLITE_DONE)
{
NSLog(#"deleted from SRNumberTable");
}
else
{
NSLog(#"not able to execute step statement");
}
}
else
{
NSLog(#"not deleted from SRNumberTable");
NSLog(#"the error is %s", sqlite3_errmsg(db));
}
sqlite3_finalize(statement);
}
else
{
NSLog(#"Not able to open database for deleting");
}
}
On console, i am getting
Application[54974:a0b] deleteCalled
2014-01-03 16:12:55.442 Application[54974:a0b] deleted from Customer Table
2014-01-03 16:12:55.443 Application[54974:a0b] deleted from KeyCodeTable
2014-01-03 16:12:55.445 Application[54974:a0b] deleted from SRNumberTable
But when i am opening the database in on mac, the data is intact there..!! What is wrong with my code?? why isn't the data getting deleted??
I think you are copying your database from bundle to documents directory. So, the updated database will be present in documents directory. You seems to look the database from your workspace which is never going to be of updated one.
Your code opens database with sqlite3_open(), but does not close it using sqlite3_close(). This means that your database is probably still in open transaction, and quite possibly has 2 files: one is main database.db, and journal file database.db-journal which contains uncommitted intent to delete your tables.
You should make sure that your application closes database before you copy database file from the device to the host. At the very least, copy both main database AND journal file as one set. It is still likely to have consistency issues, but you should see your changes.
Try instead of sqlite3_prepare_v2 to sqlite3_exec. This working fine for me.
Just Ref:
char *errMsg;
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open(dbPath, &database) == SQLITE_OK) {
NSLog(#"Db OPened ");
NSString *queryLists = [NSString stringWithFormat:#"delete from Table_name"];
const char *query_stmt = [queryLists UTF8String];
if (sqlite3_exec(database, query_stmt, NULL, NULL, &errMsg)
!= SQLITE_OK){
NSLog(#"Error %s", errMsg);
NSLog(#"Table Not Deleted");
}
}
1st thing Don't write same functionality code repeatedly in place create one function that delete all data from given table name,
2nd make sure you are looking at correct sqlite file in mac.
look this,
-(void)deleteAllData
{
[self deleteTable: CustomerNumberTable];
[self deleteTable: SRNumberTable];
[self deleteTable: KeyCodeTable];
}
-(void)deleteTable:(NSString *)table;
{
const char *dbpath=[appDelegate.databasePath UTF8String];
if (sqlite3_open(dbpath, &dtdb)==SQLITE_OK)
{
sqlite3_stmt *stmt;
const char *qry=[[NSString stringWithFormat:#"delete from %#",table] UTF8String];
sqlite3_prepare_v2(dtdb, qry, -1, &stmt, NULL);
if (sqlite3_step(stmt)==SQLITE_DONE)
{
NSLog(#"%# Table data deleted",table);
}
sqlite3_finalize(stmt);
sqlite3_close(dtdb);
}
}
I'm trying to insert some data in a SQLite 3 database in an iOS app. But i keep getting an error that is useless to me.
This is my code trying to insert:
#try {
NSString *dbPath = [self.GetDocumentDirectory stringByAppendingPathComponent:#"knhb.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if((sqlite3_open_v2([dbPath UTF8String], &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK))
{
NSLog(#"An error has occured.");
}
NSString *sqlString = [NSString stringWithFormat:#"INSERT INTO Profile (name, password) VALUES ('%#','%#')", name, password];
const char *sql = [sqlString UTF8String];
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare_v2(db, sql, 1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"%s SQLITE_ERROR '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
}
sqlite3_step(sqlStatement);
sqlite3_finalize(sqlStatement);
int lastInsert = sqlite3_last_insert_rowid(db);
NSLog(#"lastinsertid:%d", lastInsert);
sqlite3_close(db);
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
My database table Profile has three columns idProfile, name and password. But since idProfile is an int and primary key I don't have to include it because it is auto incremented.
The error I keep getting is: SQLITE_ERROR 'near "I": syntax error' (1)
I am writing to the Documents folder.
Any help is greatly appreciated.
Daan
I'm not quite sure why but i fixed it by changing the following line of code:
if(sqlite3_prepare_v2(db, sql, 1, &sqlStatement, NULL) != SQLITE_OK)
i've turned it into:
if(sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
Not sure what the 1 or -1 means. Maybe someone can elaborate?
Cheers!
I have a high scores table in my game. When the game is over, the score is shown on the screen and it gets inserted into the high scores table. I want to know how to compare the new score to the highest score in the table so I can let the user know if they achieved a high score. Below I included the code I use to update and insert the score into the table. The score being kept is an integer, globalScore.
-(void)updateScores:(NSInteger)Primary_key
{
sqlite3_stmt *statement=nil;
NSString *sql=nil;
#try
{
statement=nil;
sql=nil;
sql=[NSString stringWithFormat:#"update tblHard set Score=? where id=%d",Primary_key];
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL)!=SQLITE_OK)
{
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_bind_int(statement, 1, globalScore);
int success=sqlite3_step(statement);
if (success == SQLITE_ERROR) {
NSAssert1(0, #"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
statement=nil;
sql=nil;
}
#catch (NSException *e)
{
NSLog(#"asd");
}
}
-(int)InsertGame
{
int i=0;
sqlite3_stmt *statement=nil;
NSString *sql=nil;
#try
{
statement=nil;
sql=nil;
sql=[NSString stringWithFormat:#"insert into tblHard(Score) values (?)"];
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL)!=SQLITE_OK)
{
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_bind_int(statement, 1, globalScore);
int success=sqlite3_step(statement);
if (success == SQLITE_ERROR) {
NSAssert1(0, #"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(database));
}
i= sqlite3_last_insert_rowid(database);
sqlite3_finalize(statement);
statement=nil;
sql=nil;
}
#catch (NSException *e)
{
NSLog(#"asd");
}
return i;
}
So what I'm looking for is something like this...
if(globalScore > "the highest score in the table"){
highscorelabel.hidden=NO;
}
You can retrieve the highest score in the table with
select max(Score) from tblHard
You can retrieve the result of this SQL query with sqlite3_column_int. Here is the code (error checking removed for brevity):
int highestScore;
/* ... */
sqlite3_prepare_v2(database, "select max(Score) from tblHard", -1,
&statement, NULL);
sqlite3_step(statement);
highestScore = sqlite3_column_int(statement, 0);
And then you can compare the current maximum score with globalScore:
if (globalScore > highestScore) {
/* ... */
}