What's wrong with my iOS sqlite delete method? - ios

I am making a sqlite for iOS. I have succeeded to save data and present, but not delete.
This is my createTable Method:
- (void) createTable: (NSString *) tableName
withField1: (NSString *) field1
withField2: (NSString *) field2
withField3: (NSString *) field3
withField4: (NSString *) field4{
char *err;
NSString *sql = [NSString stringWithFormat:#"CREATE TABLE IF NOT EXISTS '%#' ('%#' "
"TEXT PRIMARY KEY, '%#' TEXT, '%#' TEXT, '%#' TEXT);", tableName, field1,field2,field3,field4];
if(sqlite3_exec(db,[sql UTF8String], NULL,NULL, &err) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, #"Could not create table");
} else {
NSLog(#"table created");
}
}
This is my saveData method:
-(void) saveNewData :(NSString*)nickname :(NSString*)url :(NSString*)uid :(NSString*)pswd{
sqlite3_stmt *statement;
if (sqlite3_open([[self filePath] UTF8String], &db) == SQLITE_OK) {
NSString *sql =[NSString stringWithFormat:#"INSERT INTO accountListDB ('nickname', 'url', 'uid', 'pswd') VALUES ('%#', '%#', '%#', '%#')", nickname, url, uid, pswd];
const char *insert_stmt = [sql UTF8String];
sqlite3_prepare_v2(db, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(#"data added");
}else{
NSLog(#"failed to added");
}
sqlite3_finalize(statement);
sqlite3_close(db);
}
}
This is my deleteData method, which is not working:
-(void) deleteData:(NSString*)nickname :(NSString*)url :(NSString*)uid :(NSString*)pswd{
sqlite3_stmt *statement;
if (sqlite3_open([[self filePath] UTF8String], &db) == SQLITE_OK) {
NSString *sql =[NSString stringWithFormat:#"DELETE FROM accountListDB WHERE nickname = %#", nickname];
const char *delete_stmt = [sql UTF8String];
sqlite3_prepare_v2(db, delete_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(#"data deleted");
}else{
NSLog(#"failed to delete");
}
sqlite3_finalize(statement);
sqlite3_close(db);
}
}
It returns failed to delete.

I think you need to put single quote between your nickename in the query because if it contain space inside that it will not delete the records. Change your delete statement like this
NSString *sql = [NSString stringWithFormat:#"DELETE FROM accountListDB WHERE nickname = '%#'", nickname];

Related

Sqlite database locked error - iOS

I'm using sqlite to use insert and update the data in table view. I can able to update the data only once, on the next attempt it showing database locked. Even though am closing the database, please help. Below is the code.
-(void)saveUserCredential: (NSString *)email :(NSString *)userName :(NSString *)loginTime :(NSString *)source
{
NSDateFormatter *dateformate=[[NSDateFormatter alloc]init];
[dateformate setDateFormat:#"yyyy-MM-dd HH:mm"]; // Date formater
NSString *todayDate = [dateformate stringFromDate:[NSDate date]];
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString * query = #"SELECT * from users";
int rc =sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL);
if(rc == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *updateSQL = [NSString stringWithFormat:#"update users set email = '%#', username = '%#', source = '%#', created = '%#' where id = '%d'",email, userName, source, todayDate,1];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL );
//sqlite3_bind_int(statement, 1, 1);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"successfully updated");
}
else{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
}
else
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into users (email,username,source,created) values('%#','%#','%#','%#')",email,userName,source,todayDate];
NSLog(#"INS SQL: %#", insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"INSERTED");
}
else
{
NSLog(#"NOT INSERTED");
}
NSLog(#"hello ");
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
}
You need to call
sqlite3_finalize(statement);
for each successful sqlite_prepare_v2 call. It should be balanced. Also use different sqlite3_stmt for each query.
So your code need to be changed like:
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString * query = #"SELECT * from users";
int rc =sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL);
if(rc == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *updateSQL = [NSString stringWithFormat:#"update users set email = '%#', username = '%#', source = '%#', created = '%#' where id = '%d'",email, userName, source, todayDate,1];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_stmt *upStmt;
sqlite3_prepare_v2(database, update_stmt, -1, &upStmt, NULL );
//sqlite3_bind_int(upStmt, 1, 1);
if (sqlite3_step(upStmt) == SQLITE_DONE)
{
NSLog(#"successfully updated");
}
else
{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(upStmt);
}
else
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into users (email,username,source,created) values('%#','%#','%#','%#')",email,userName,source,todayDate];
NSLog(#"INS SQL: %#", insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_stmt *inStmt;
sqlite3_prepare_v2(database, insert_stmt,-1, &inStmt, NULL);
if (sqlite3_step(inStmt) == SQLITE_DONE)
{
NSLog(#"INSERTED");
}
else
{
NSLog(#"NOT INSERTED");
}
NSLog(#"hello ");
sqlite3_finalize(inStmt);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}

Insert records in sqlite database

I have a sqlite db and i want to insert row in it . I used this code .
-(void)InsertRecords{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO notes (id, title, content,dataAdd,category) VALUES (\"%#\", \"%#\", \"%#\" ,\"%#\",\"%#\")",
#"1",
#"mountain",
#"Prahova",
#"12.09.2019",
#"public"];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_stmt *updateStmt = nil;
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if(sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"data inserted");
}
else{
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
}
}
else{
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
and it's log : data inserted .
When i do this :
querySQL1 = #"select id from notes where category LIKE 'public'";
const char *query_stmt = [querySQL1 UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
NSString *idNr;
while (sqlite3_step(statement) == SQLITE_ROW)
{
idNr =[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
NSLog(#"%#",idNr);
idNr is null .
ANy ideea what is happening ? Any help will be appreciate . Thanks.
The NSString allocation was wrong statement, There were no need to alloc NSString object.
I changed :
NSString *idNr=#"";
while (sqlite3_step(statement) == SQLITE_ROW)
{
idNr =[NSString stringWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
Try to use this snippet:
sqlite3 *database;
if (sqlite3_open(<#DBPath#>, &database)
!= SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Failed to open database");
return nil;
}
char *update = "INSERT OR REPLACE INTO <#Table name#> (<#key1#>,<#key2#>) VALUES (?,?);";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil)
== SQLITE_OK) {
sqlite3_bind_text(stmt, <#the index#>,<#The text value#> , -1, NULL);
sqlite3_bind_int(stmt, <#the index#>, <#the int value#>);
}
if (sqlite3_step(stmt) != SQLITE_DONE){
NSLog(#"Error inserting version in table <#tablename#>");
return;
}
sqlite3_finalize(stmt);
sqlite3_close(database);
It uses the sqlite3_bind* functions to bind the values to the keys.

Data not getting deleted from database using SQLite

I have loaded some data in my tableview using SQLite database in the format 1) some value, 2) some value so on. 1 and 2 are primary key, this is my code for delete which I have put on the swipe on delete function of the table view
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self openDB];
NSString *idofTable = [NSString new];
NSScanner *scanner = [[NSScanner alloc] initWithString:[self.tableLogView cellForRowAtIndexPath:indexPath].textLabel.text];
[scanner scanUpToString:#")" intoString:&idofTable];
NSLog(#"id=%#, text=%#", idofTable, [self.tableLogView cellForRowAtIndexPath:indexPath].textLabel.text);
if(editingStyle==UITableViewCellEditingStyleDelete)
{
char *error;
NSString *sql = [NSString stringWithFormat:#"DELETE FROM History WHERE 'id' = '%#'", idofTable];
NSLog(#"%#",sql);
if(sqlite3_exec(db, [sql UTF8String], NULL, NULL,&error)!=SQLITE_OK)
{
sqlite3_close(db);
NSAssert(0,#"Could not create table");
}
else
{
NSLog(#"Data Deleted");
sqlite3_exec(db, "COMMIT", NULL, NULL, &error);
}
}
[tableLogView reloadData];
}
The log "Data Deleted" gets printed but the data doesnt get deleted in database nor in tableview. Any help appreciated. I dont know where the error is occuring, the query seems to be correct.
Try This
if(editingStyle==UITableViewCellEditingStyleDelete)
{
NSString *dbFilePath =[DBclass getDBPath];
sqlite3_stmt *deleteStmt = nil;
if(sqlite3_open([dbFilePath UTF8String], &database)==SQLITE_OK)
{
NSString *deleteString=[NSString stringWithFormat:#"delete from table where ID =%d",idValue];
const char *sql =[deleteString UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &deleteStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating delete view statement. '%s'", sqlite3_errmsg(database));
if(SQLITE_DONE != sqlite3_step(deleteStmt))
NSAssert1(0, #"Error while deleting data. '%s'", sqlite3_errmsg(database));
else
NSLog(#"Success in deleting the medicine.");
sqlite3_close(database);
}
}
[tableLogView reloadData];
You arent finalising nor closing the Database.
sqlite3_finalize(stmt);
sqlite3_close(DB);
This is the right way to delete a row:
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSString *sql = [NSString stringWithFormat:#"DELETE FROM History WHERE 'id' = '%#'", idofTable];
const char *del_stmt = [sql UTF8String];
sqlite3_prepare_v2(contactDB, del_stmt, -1, & deleteStmt, NULL);
if (sqlite3_step(deleteStmt) == SQLITE_DONE)
{
NSLog(#"Data Deleted");
sqlite3_exec(db, "COMMIT", NULL, NULL, &error);
}else {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
}
sqlite3_finalize(deleteStmt);
sqlite3_close(contactDB);
}

if (sqlite3_step(statement) == SQLITE_DONE) loop does not execute - iOS

below is my code to update records in database...
-(BOOL) addScoreInDatabase:(classname *)objGames
{
BOOL success;
sqlite3 *database;
const char *dbpath = [self.databasePath UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
sqlite3_stmt *statement;
NSData *strJson = [objGames getJSON];
NSString *strContent = [[[[NSString alloc]
initWithData:strJson encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:#"\\" withString:#""]stringByReplacingOccurrencesOfString:#"null" withString:#"\"\""];
NSLog(#"strcom %#",strContent);
NSString *query = [NSString stringWithFormat:#"UPDATE gamescore SET data ='%#' WHERE id = 1",strContent];
NSLog(#"query %#",query);
const char *sqlStatement = [query UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, & statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = TRUE;
}
else
{
success = FALSE;
}
sqlite3_exec(database, "VACUUM;", 0, 0, nil);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return success;
}
and it doesn't go inside if (sqlite3_step(statement) == SQLITE_DONE) loop
and Resulted query is
UPDATE gamescore SET data ='{
"title" : "pacman",
"time" : "55",
"score" : "200",
"level" : "1"
}' WHERE id = 1
and when i execute this query in Sqlite Manager it doesn't update the records instead it shows something like this
Can anybody help me to update my records ?!..Thanks !!
You can use sqlite3_exec() method instead of sqlite3_step().
sqlite3_exec() will execute whatever the query you have given.
Try this out.
enter code
-(BOOL) addScoreInDatabase:(classname *)objGames
{
BOOL success;
sqlite3 *database;
const char *dbpath = [self.databasePath UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
sqlite3_stmt *statement;
NSData *strJson = [objGames getJSON];
NSString *strContent = [[[[NSString alloc]
initWithData:strJson encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:#"\\" withString:#""]stringByReplacingOccurrencesOfString:#"null" withString:#"\"\""];
NSLog(#"strcom %#",strContent);
NSString *query = [NSString stringWithFormat:#"UPDATE gamescore SET data ='%#' WHERE id = 1",strContent];
NSLog(#"query %#",query);
const char *sqlStatement = [query UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, & statement, NULL) == SQLITE_OK)
{
sqlite3_exec(database, "VACUUM;", 0, 0, nil);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return success;
}

SQLite iOS Insert data

Im trying to insert just one name to my sqlite file. im using this code but it's not working :/
-(void)InsertRecords:(NSMutableString *) txt{
if(addStmt == nil) {
const char *sql = "INSERT INTO myMovies (movieName) VALUES(?) ";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
else
sqlite3_bind_text(addStmt, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
}
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
sqlite3_reset(addStmt);
}
pass your query to this method and try,
-(void)Insertdata:(NSString*)query{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"YourDBName.sql"];
if(sqlite3_open([databasePath UTF8String],&db) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"%#",query];
char *errmsg=nil;
if(sqlite3_exec(db, [querySQL UTF8String], NULL, NULL, &errmsg)==SQLITE_OK)
{
NSLog(#".. Row Added ..");
}
}
sqlite3_close(db);
}
An "out of memory" error from sqlite typically means the database handle you are using hasn't been opened yet. Make sure you are calling sqlite3_open_v2 with the database variable shown in the code you posted?
ok finally I made it ! this is the code that I used for everyone who need it :
-(void)InsertRecords:(NSMutableString *)txt{
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"movieData.sqlite"];
const char *dbpath = [dbPath UTF8String];
sqlite3 *contactDB;
sqlite3_stmt *statement;
NSLog(#"%#",dbPath);
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO myMovies (movieName) VALUES (\"%#\")", txt];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
sqlite3_bind_text(statement, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
} else {
NSLog(#"error");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
Try this:
//save our data
- (BOOL) saveEmployee:(Employee *)employee
{
BOOL success = false;
sqlite3_stmt *statement = NULL;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &mySqliteDB) == SQLITE_OK)
{
if (employee.employeeID > 0) {
NSLog(#"Exitsing data, Update Please");
NSString *updateSQL = [NSString stringWithFormat:#"UPDATE EMPLOYEES set name = '%#', department = '%#', age = '%#' WHERE id = ?",
employee.name,
employee.department,
[NSString stringWithFormat:#"%d", employee.age]];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(mySqliteDB, update_stmt, -1, &statement, NULL );
sqlite3_bind_int(statement, 1, employee.employeeID);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
else{
NSLog(#"New data, Insert Please");
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO EMPLOYEES (name, department, age) VALUES (\"%#\", \"%#\", \"%#\")",
employee.name,
employee.department,
[NSString stringWithFormat:#"%d", employee.age]];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(mySqliteDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
sqlite3_finalize(statement);
sqlite3_close(mySqliteDB);
}
return success;
}

Resources