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).
Related
I'm insert data into sqlite database and I've seen NSLog(#"DONE") on my console result, but I don't see the data update in my sqlite database file. Pls help me !!!
Here my code to save data:
- (void)saveData:(NSString *)_Id
{
sqlite3_stmt *statement;
NSString *_databasePath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"data.db"];
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &db) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO MyTable (id) VALUES (\"%#\")", _Id];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(db, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"DONE");
} else {
NSLog(#"Failed to add contact");
}
sqlite3_finalize(statement);
sqlite3_close(db);
}
}
You are opening the database in your bundle. The bundle is read-only on the device. You must copy the database to your Documents folder (if it doesn't exist there already) and open it from there.
Also be aware that you're dealing with multiple copies of the database (the one in your project, the one in the bundle and now the one in the device/simulator's Documents folder). Make sure you're checking for the inserted record in the correct database (the one in Documents)
As an aside, you should also check to see that sqlite3_prepare_v2 returned SQLITE_OK and if not, log sqlite3_errmsg.
You should also use ? placeholder in your SQL and bind values using sqlite3_bind_text (or, if it's possibly nil, sqlite_bind_null):
- (void)saveData:(NSString *)_Id
{
sqlite3_stmt *statement;
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath ] stringByAppendingPathComponent:#"data.db"];
NSString *documentsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *documentsPath = [documentsFolder stringByAppendingPathComponent:#"data.db"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:documentsPath isDirectory:NO]) {
NSError *error;
if (![fileManager copyItemAtPath:bundlePath toPath:documentsPath error:&error]) {
NSLog(#"database copy failed: %#", error);
}
}
const char *dbpath = [documentsPath UTF8String];
if (sqlite3_open(dbpath, &db) == SQLITE_OK) {
const char *insertSql = "INSERT INTO MyTable (id) VALUES (?)";
if (sqlite3_prepare_v2(db, insertSql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(#"prepare error: %s", sqlite3_errmsg(db));
}
// bind a value to the ? placeholder in the SQL
if (_Id) {
if (sqlite3_bind_text(statement, 1, [_Id UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK) {
NSLog(#"bind text error: %s", sqlite3_errmsg(db));
}
} else {
if (sqlite3_bind_null(statement, 1) != SQLITE_OK) {
NSLog(#"bind null error: %s", sqlite3_errmsg(db));
}
}
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(#"DONE");
} else {
NSLog(#"Failed to add contact: %s", sqlite3_errmsg(db));
}
sqlite3_finalize(statement);
sqlite3_close(db);
}
}
Most people move that "if database doesn't exist in documents, then copy it from the bundle and open it from there" logic inside a dedicated openDatabase method, but hopefully this illustrates the idea.
in my application I have stored the data in my sqlite3 database and uploading all my sqlite3 database to my online sever, once it copied to my server, I want to delete all my records I have stored in my local database.
I have two view controller first view controller, where I store the data to sqlite3 second view controller I have used to load the data to my server I have given like if user connected to network it has to upload the data.
I want like after uploading data to my server I want to delete all the records in my local database.
I have already tried some method its not working please tell me how to resolve this.
- (void) Delete_LoginData
{
if(sqlite3_open([self.filePath UTF8String], &db) == SQLITE_OK)
{
const char *sql = "DELETE * FROM reg";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, sql,-1, &statement, NULL) == SQLITE_OK)
{
sqlite3_reset(statement);
}
}
}
I called this function in my Reachability.
- (BOOL)reachable
{
Reachability *reach = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [reach currentReachabilityStatus];
if(internetStatus == NotReachable)
{
}
else
{
[self Delete_LoginData];
}
return YES;
}
My file path.
- (NSString *) filePath
{
NSArray *paths = filepath, YES);
return [[paths objectAtIndex:0] stringByAppendingPathComponent:#"bp.sqlite"];
}
Code open the db.
- (void)openDB
{
if (sqlite3_open([[self filePath] UTF8String], &db)!=SQLITE_OK)
{
sqlite3_close(db);
NSAssert(0, #"Database failed to open");
}
else
{
NSLog(#"database opened");
}
}
I have used this above method to delete record from my local database its not working please to where I'm doing wrong.
Thanks.
Use sqlite3_step instead of sqlite3_reset to execute the query
if(sqlite3_open([self.filePath UTF8String], &db) == SQLITE_OK)
{
const char *sql = "DELETE FROM reg";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, sql,-1, &statement, NULL) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_DONE){
// executed
}else{
//NSLog(#"%s",sqlite3_errmsg(db))
}
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
sqlite3_prepare_v2 doesn't act the execution You need to take a step into it
if(sqlite3_open([self.filePath UTF8String], &db) == SQLITE_OK){
NSString *sql = "DELETE FROM reg";
const char *query_st = [sql UTF8String];
if(sqlite3_prepare_v2(database, query_st, -1, &statement, NULL) == SQLITE_OK){
// Loop through the results and add them to the feeds array
if(sqlite3_step(statement) == SQLITE_DONE) {
// Deleted records,....
}else{
NSAssert1(0,#"Error when counting rows %s",sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
You can do like this,
sqlite3_stmt *statement;
- (void) Delete_LoginData
{
// Open database first
if(sqlite3_open([self.filePath UTF8String], &db) == SQLITE_OK)
{
// Sql query
const char *sql = "DELETE FROM reg";
// We are preparing the statement here
if(sqlite3_prepare_v2(db, sql,-1, &statement, NULL) == SQLITE_OK)
{
// If that prepared statement is OK then we can execute that statement
if(sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#" Records deleted successfully..");
}
else
{
NSLog(#" Opppsss..... Unable to delete records..");
}
}
// Finalizing the statement
sqlite3_finalize(statement);
// Closing the database
sqlite3_close(db);
}
Hope this work for you...
Thank you...
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);
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));
this is what i am doing in header
static sqlite3 *database = nil;
static sqlite3_stmt *deleteStmt = nil;
#implementation SQLAppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize coffeeArray;
this is what i am using for deleting raw
- (void) removeCoffee:(NSNumber *)coffeeObj {
NSLog(#"coffeeObj%#",coffeeObj);
int myInteger = [coffeeObj integerValue];
NSLog(#"myInteger%d",myInteger);
// print this myInteger0
NSLog(#"%#",coffeeArray);
//print object
if (sqlite3_open([self getDBPath], &database) == SQLITE_OK)
{
NSLog(#"myInteger%#",[self getDBPath]);
NSString *sql = [NSString stringWithFormat: #"delete from Coffee where CoffeeID =%d",myInteger];
const char *del_stmt = [sql UTF8String];
NSLog(#"%#",del_stmt); // getting print
// print this delete from Coffee where CoffeeID =0.
sqlite3_prepare_v2(database, del_stmt, -1, & deleteStmt, NULL);
NSLog(#"sqlite3_step(deleteStmt) == SQLITE_DONE%#",sqlite3_step(deleteStmt) == SQLITE_DONE);
// this print null
if (sqlite3_step(deleteStmt) == SQLITE_DONE)
{
//NSLog(#"hi") this is not getting print
} else {
//NSLog(#"hi") this is getting print
}
sqlite3_finalize(deleteStmt);
sqlite3_close(database);
[coffeeArray removeObjectAtIndex:myInteger];
NSLog(#"%#",coffeeArray);
// object is deleted
}
}
my table is like below
table name = Coffee
CoffeeID(INTEGER)=0
CoffeeName(VARCHAR)=Latte
Price(REAL)=2.99
where thing runs perfectly object get deleted from array and thats why its not appearing on table cell. but its not getting deleted from database table thats why it when i launch app again then it shows again please help what i am doing wrong.
Before start deleting the object just conform once the database is opened properly or not. Just try like this.
//Setting path
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"database.db"]];
const char *dbpath=[databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat: #"delete from Coffee where CoffeeID =%d",myInteger];
const char *del_stmt = [sql UTF8String];
sqlite3_prepare_v2(database, del_stmt, -1, & deleteStmt, NULL);
if (sqlite3_step(deleteStmt) == SQLITE_DONE)
{
} else {
}
sqlite3_finalize(deleteStmt);
sqlite3_close(database);
[coffeeArray removeObjectAtIndex:myInteger];
NSLog(#"%#",coffeeArray);
// object is deleted
}
if(sqlite3_open([[self filepath] UTF8String], &db) == SQLITE_OK)
{
Deletestatement = nil;
if(Deletestatement == nil)
{
const char *sql = "delete from Sqlitemanager2;";
if(sqlite3_prepare_v2(db, sql, -1, &Deletestatement, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating delete statement. '%s'", sqlite3_errmsg(db));
}
if (SQLITE_DONE != sqlite3_step(Deletestatement)) //prathibha for problem in if
NSAssert1(0, #"Error while deleting. '%s'", sqlite3_errmsg(db));
sqlite3_finalize(Deletestatement);
}
I hope this will help you.