Delete all rows in sqlite database not working - iOS - ios

Im having an issue deleting all the rows in a sqlite table I created, I can delete from this table based on a condition, (name, date etc) however when I try to delete all the contents in the table it fails: Here is what I've tried:
-(void) deleteFromDB{
NSLog(#"delete from DB method being called");
NSString * deleteQuery = #"DELETE * FROM CLUB";
[self deleteData:deleteQuery];
}
-(void)deleteData:(NSString *)deleteQuery{
char *error;
NSLog(#"Enter deleteData");
if (sqlite3_exec(clubDB, [deleteQuery UTF8String], NULL, NULL, &error)==SQLITE_OK) {
NSLog(#"CLUB info deleted");
}else{
NSLog(#"Failed");
NSLog(#"Failed with %s", error);
}
}
I get an output of failed.
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
cant delete is never printed
The error message is:
X”¿
*Update**
clubDB is of type sqlite3 (declared in .h as sqlite3*clubDB
error string updated above
**Update2*****
Here is the code for opeing/creating the database:
-(void) createOrOpenDB{
NSArray * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:#"club.db"];
NSLog(#"path = %#",dbPathString);
char*error;
NSFileManager*fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:dbPathString]){
const char * dbPath = [dbPathString UTF8String];
//create db here
if (sqlite3_open(dbPath, &clubDB)==SQLITE_OK) {
NSLog(#"success");
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CLUB (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, SUBJECT TEXT)";
sqlite3_exec(clubDB, sql_stmt, NULL, NULL, &error);
sqlite3_close(clubDB);
}
}
}

Your delete statement isn't valid SQL. To delete everything from CLUB it would be:
delete from CLUB
You don't need the star as it obviously affects the whole record.

Related

Failing to Update/Delete record in Sqlite from IOS App

I'm creating an iPhone App which uses Sqlite to persist data,While i do insert/select operations the code works fine,but for update /delete operations code gets failed.
I found some links n stacker flow reg the same and some how i fixed SQLITE_BUSY Error using BEGIN Transaction and Commit statements surrounded my update/delete statements.Now if I execute he Update/delete statements,it returns SQLITE_OK :0 : Successful results.Also embedding the code here.I request the developers to please let me know where i went wrong.
For testing purpose I hardcoded the values like
"update drug set drugdose='2' where drugid=1".
After exe the statement it returns SQLITE_OK,but if I check the Database, the values are not getting updated.
enclosing two approaches i followed.
(BOOL )updateDrugDetails:(DrugDetails *)drugDetails{
BOOL *status=TRUE;
NSString *databasePath;
sqlite3 *database ;
NSString *docsDir;
NSArray *dirPaths;
sqlite3_stmt *updateStatement;
BOOL statusUpdate;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString:
[docsDir stringByAppendingPathComponent: #"drugdb2.sqlite"]];
BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
NSLog(#"databasePath %#",databasePath);
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
NSLog(#"Failed to open/create database");
isSuccess = NO;
}
else
{
isSuccess = YES;
NSLog(#"Able to open/create database");
}
if(isSuccess)
{
NSInteger drugID= [drugDetails drugId];
NSString *drugDose= [drugDetails drugDose];
NSString *drugStartDate= [drugDetails drugStartDate];
NSString *drugEndDate= [drugDetails drugEndDate];
const char *dbpath = [databasePath UTF8String];
NSString *temp=[NSString stringWithFormat:#"%d", drugID];
int tempInt=[temp integerValue];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
/*
// First Approach
*updateSQL =
[NSString stringWithFormat:
#"update drug set drugdose=?,drugstartdate=? ,drugenddate=?
where drugid =?"];
const char *update_stmt = [updateSQL UTF8String];
const char *drgDose = [drugDose UTF8String];
const char *drgStartDate = [drugStartDate UTF8String];
const char *drgEndDate= [drugEndDate UTF8String];
sqlite3_prepare_v2(database, update_stmt,-1, &updateStatement, NULL);
// sqlite3_bind_text(updateStmt, 4, [name.text UTF8String],
-1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStatement, 1, drgDose,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(updateStatement, 2, drgStartDate,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(updateStatement, 3, drgEndDate,-1,SQLITE_TRANSIENT);
sqlite3_bind_int(updateStatement, 4, tempInt);
sqlite3_busy_timeout(database, -1);
int updtStatus;
updtStatus=sqlite3_step(updateStatement);
if (updtStatus == SQLITE_DONE)
{
NSLog(#"Drug Details Updated with Status and rem Count");
statusUpdate= YES;
}else
{
NSLog(#"Failed to Update Drug Deatils with Status
rem Count%d",updtStatus);
statusUpdate= NO;
}
if(statusUpdate==TRUE)
{
NSLog(#"drug updated");
status=TRUE;
// sqlite3_reset(updateStatement);
sqlite3_finalize(updateStatement);
sqlite3_close(database);
database=nil;
databasePath=nil;
updateStatement=nil;
databasePath =nil;
}
else
{
NSLog(#"Error: %d", statusUpdate);
status=FALSE;
// sqlite3_reset(updateStatement);
sqlite3_finalize(updateStatement);
sqlite3_close(database);
database=nil;
databasePath=nil;
updateStatement=nil;
databasePath =nil;
}
sqlite3_finalize(updateStatement);
sqlite3_close(database);
*/
// Second Approach ,Inspite of hardcoding the values for testing purpose,its not updating //in DB.
NSString *replaceStatement =
[NSString stringWithFormat:#"update drug set
drugdose='2',drugstartdate='10/10/10',drugenddate='10/10/10' where drugid=1"];
char *error;
int updateStatus;
// sqlite3_busy_timeout(database, -1);
NSString *begTxn=#"BEGIN TRANSACTION;";
NSString *commit=#"COMMIT;";
sqlite3_exec(database,[begTxn UTF8String],NULL,NULL,&error);
updateStatus= sqlite3_exec(database,
[replaceStatement UTF8String], NULL, NULL, &error);
// Here the updatStatus returns 0 ,i.e sqlite Success Operatiion
sqlite3_exec(database,[commit UTF8String],NULL,NULL,&error);
if ((updateStatus == 0))
{
NSLog(#"Drug Details updated");
sqlite3_close(database);
}
else
{
NSLog(#"Error while Updating Drug Details %s", error);
sqlite3_close(database);
}
}
else
{
NSLog(#"Failed to Open Dtabase");
status=FALSE;
}
}else
{
NSLog(#"Failed to get the DB Path");
status=FALSE;
}
return status;
}

(Objective C) Save changes in sqlite database

I'm creating an app for my school project that has to write data to my sqlite database. It works, as long as the app is running active but as soon as the app closes, my added data is gone and when I want to read this data this will not work off course. I included both my loadData and saveData methods. The two database paths are the same in both functions so it's not that I'm writing my data elsewhere. I really can't find the solution or the problem. I even get the insert success in my output, so the insert is successful.
- (void) saveData:(id)sender{
NSString *sqldb = [[NSBundle mainBundle] pathForResource:#"PXLate" ofType:#"sqlite3"];
sqlite3_stmt *stmt;
NSString *queryInsert = #"INSERT INTO assignments (name, lesson, dueDate, notification, start, at) VALUES ('abc','abc', 'abc', 1, 'abc', 'abc')";
NSLog(#"%#",sqldb);
NSLog(#"%#",queryInsert);
if(sqlite3_open([sqldb UTF8String], &_PXLate) == SQLITE_OK)
{
sqlite3_prepare_v2(_PXLate, [queryInsert UTF8String], -1, &stmt, NULL);
if(sqlite3_step(stmt)==SQLITE_DONE)
{
NSLog(#"insert success");
}
else
{
NSLog(#"insert un success");
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(_PXLate));
}
int success=sqlite3_step(stmt);
if (success == SQLITE_ERROR)
{
NSAssert1(0, #"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(_PXLate));
//[_PXLate save:&error];
} sqlite3_finalize(stmt);
}
sqlite3_close(_PXLate);
}
and my loadData function
- (void) loadData:(id)sender
{
//path for database
NSString *sqldb = [[NSBundle mainBundle] pathForResource:#"PXLate" ofType:#"sqlite3"];
//check if present
NSFileManager*fm=[NSFileManager defaultManager];
NSLog(#"path: %#", sqldb);
const char *dbpath = [sqldb UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_PXLate) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT * FROM assignments WHERE name='abc'", _label.text];
const char *query_stmt = [querySQL UTF8String];
NSLog(#"name");
NSLog(querySQL);
int response = sqlite3_prepare_v2(_PXLate, query_stmt, -1, &statement, NULL);
NSLog(#"response %d", response);
if (response == SQLITE_OK)
{
NSLog(#"name");
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *namefield = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
NSLog(#"name:%#", namefield);
_label.text = namefield;
} else {
_label.text = #"Match not found";
}
sqlite3_finalize(statement);
}
sqlite3_close(_PXLate);
}
}
You have to copy your sqlite to the documents directory and then work with that. Example:
self.databaseName = #"databasename.sqlite";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
self.databasePath = [[NSString alloc]init];
self.databasePath = [documentsDir stringByAppendingPathComponent:self.databaseName];
[self checkAndCreateDatabase];
And the create method:
-(void)checkAndCreateDatabase
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
}
A couple of observations:
As Retterdesdialogs said, you should
Check for existence of database in Documents;
If not there, copy from bundle to Documents; and
Open database from Documents.
You should not open database from bundle, because on the device that folder is read-only.
In your INSERT statement you are not checking the response of sqlite3_prepare_v2, which is a very common source of errors. If this is not SQLITE_OK, you should immediately log sqlite3_errmsg, before you call sqlite3_step.
You are performing sqlite3_step twice in the INSERT statement.
In loadData, you are not logging sqlite3_errmsg if sqlite3_prepare_v2 failed. Always look at sqlite3_errmsg upon any error.

sqlite db creation + objective-c + cordova

I am creating an app in IOS with cordova 2.1.0 framework. I am doing following to create the db:
NSFileManager *fileManager = [NSFileManager defaultManager];
//NSError *error;
if (![fileManager fileExistsAtPath:self.databaseFile]) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
self.databaseFile = [documentsDirectory stringByAppendingPathComponent:#"klb_db.sqlite"];
[self createConfigTable];
} else {
NSLog(#"fail to create database");
}
// to create config table
-(void) createConfigTable{
NSString *createStmt = #"CREATE TABLE IF NOT EXISTS config (id INTEGER PRIMARY KEY AUTOINCREMENT,key text,value text);";
// Open the database and or create it
if (sqlite3_open_v2([self.databaseFile UTF8String], &databaseHandle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , NULL) == SQLITE_OK)
{
NSLog(#"database created");
const char *sqlStatement = [createStmt UTF8String];
char *error;
if (sqlite3_exec(databaseHandle, sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
NSLog(#"Config table created.");
}
}
else{
sqlite3_close(databaseHandle);
}
sqlite3_close(databaseHandle);
return;
}
Then, in cordova index.html , i am trying to run a query in the db created above as:
dbName = 'Database';
//to insert username, password into db
db = window.openDatabase(dbName, "1.0", gAppConfig.dbMessage, 200000);
db.transaction(querySelectConfig, errorQuery);
//Get Messages from the DB
function querySelectConfig(tx) {
alert('select config')
tx.executeSql('SELECT * FROM "'+gAppConfig.configTable+'";', [], querySelectSuccess, errorQuery);
}
In the function querySelectConfig(), the query is failing. Why is the query failing. Is the db creation process flawed in objective-c. And secondly, what is the utility of klb_db.sqlite file. When a new database is created, does it need to be blank. And how is .sqlite file created.
Use core data, it will save you time
http://developer.apple.com/library/mac/documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html

cannot insert value to sqlite DB iOS

Well following this tutorial I have some problems in inserting values to my DB although everything seems to be working fine.
This is my code for inserting entries.
-(void)insertOrder:(MyOrderList*)entry
{
// Create insert statement for the person
NSString *insertStatement = [NSString stringWithFormat:#"INSERT INTO LIST (URL, CODE, EMAIL, FULL) VALUES (\"%#\", \"%#\", \"%#\",\"%#\")", entry.db_url, entry.db_code, entry.db_email,entry.db_full];
NSLog(#"SQL INSERTION COMMAND:%#",insertStatement);
char *error;
if ( sqlite3_exec(databaseHandle, [insertStatement UTF8String], NULL, NULL, &error) == SQLITE_OK)
{
NSLog(#"Order inserted.");
}
else
{
NSLog(#"Error: %s", error);
}
}
And I can see "Order Inserted" being printed out.
This is my code for retrieving the list.
-(NSArray*) getList
{
NSMutableArray *persons = [[NSMutableArray alloc]init];
NSString *queryStatement = [NSString stringWithFormat:#"SELECT URL,CODE ,MAIL, FULL FROM LIST"];
sqlite3_stmt *statement;
NSLog(#"Query:%#",queryStatement);
if (sqlite3_prepare_v2(databaseHandle, [queryStatement UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
// Iterate over all returned rows
while (sqlite3_step(statement) == SQLITE_ROW) {
NSLog(#"Url of my List is:%#",[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)]);
MyOrderList *person = [[MyOrderList alloc]initWithUrl:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)] andCode:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)] andEmail:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 2)] andFull:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 3)]];
[persons addObject:person];
// Release the person because the array takes ownership
//[person release];
}
sqlite3_finalize(statement);
}
//return [persons autorelease];
return persons;
}
and this is how I use it in my .m file
DataController *dataController = [[DataController alloc]init];
[dataController initDatabase];
//[dataController release];
MyOrderList *order = [[MyOrderList alloc] initWithUrl:url_2 andCode:keycode andEmail:mail andFull:full_2 ];
[dataController insertOrder:order];
//data has been added
NSMutableArray* persons = [dataController getList];
and I see that persons are 0.
From terminal I see this:
Admins-MacBook-Air:~ admin$ sqlite3 Users/admin/Library/Application\ Support/iPhone\ Simulator/5.1/Applications/1A70F53B-133E-46AE-833E-13F205EA96EA/Documents/sqlite.db
SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
Error: unable to open database "Users/admin/Library/Application Support/iPhone Simulator/5.1/Applications/1A70F53B-133E-46AE-833E-13F205EA96EA/Documents/sqlite.db": unable to open database file
Admins-MacBook-Air:~ admin$
it's like my db is not even created.
this is my code for creating the DB.
-(void)initDatabase
{
// Create a string containing the full path to the sqlite.db inside the documents folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"sqlite.db"];
NSLog(#"Path is:%#",databasePath);
// Check to see if the database file already exists
bool databaseAlreadyExists = [[NSFileManager defaultManager] fileExistsAtPath:databasePath];
// Open the database and store the handle as a data member
if (sqlite3_open([databasePath UTF8String], &databaseHandle) == SQLITE_OK)
{
// Create the database if it doesn't yet exists in the file system
if (!databaseAlreadyExists)
{
// Create the PERSON table
const char *sqlStatement = "CREATE TABLE IF NOT EXISTS LIST (ID INTEGER PRIMARY KEY AUTOINCREMENT, URL TEXT, CODE TEXT, EMAIL TEXT, FULL TEXT)";
char *error;
if (sqlite3_exec(databaseHandle, sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
NSLog(#"Database and tables created.");
}
else
{
NSLog(#"Error: %s", error);
}
}
}
}

SQLite table not created

I have in my viewDidLoad() the below codes:
// Create a string containing the full path to the sqlite.db inside the documents folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"sqlite.db"];
// Check to see if the database file already exists
bool databaseAlreadyExists = [[NSFileManager defaultManager] fileExistsAtPath:databasePath];
// Open the database and store the handle as a data member
if (sqlite3_open([databasePath UTF8String], &databaseHandle) == SQLITE_OK)
{
// Create the database if it doesn't yet exists in the file system
if (!databaseAlreadyExists)
{
// Create the PERSON table
const char *sqlStatement = "CREATE TABLE IF NOT EXISTS PERSON (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIRSTNAME TEXT, LASTNAME TEXT, BIRTHDAY DATE)";
char *error;
if (sqlite3_exec(databaseHandle, sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
// Create the ADDRESS table with foreign key to the PERSON table
sqlStatement = "CREATE TABLE IF NOT EXISTS ADDRESS (ID INTEGER PRIMARY KEY AUTOINCREMENT, STREETNAME TEXT, STREETNUMBER INT, PERSONID INT, FOREIGN KEY(PERSONID) REFERENCES PERSON(ID))";
if (sqlite3_exec(databaseHandle, sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
NSLog(#"Database and tables created.");
}
else
{
NSLog(#"Error: %s", error);
}
}
else
{
NSLog(#"Error: %s", error);
}
}
}
sqlite3_close(databaseHandle);
And I am expecting that both tables are created in the folder /Users/*/Library/Application Support/iPhone Simulator/5.1/Applications/*/Documents/.
But when I went to that folder and type sqlite3 and .schema, nothing shows up.
I did see that sqlite.db is created in that folder though.
Do you know why?
after copying the db ,
create table programmatically ..it will work for sure!!!!

Resources