iOS Sqlite3 Delete Query Not Deleting Row - iphone

I am using this code to delete a row from the database for my ipad application,
-(BOOL) removeSegmentWithSegmentId:(NSInteger)sId
{
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
sqlite3_stmt *statement;
NSString *removeKeyword =[NSString stringWithFormat:#"DELETE FROM segment WHERE segment.segment_id = %d",sId];
const char *query = [removeKeyword UTF8String];
NSLog(#"%#",removeKeyword);
//if(sqlite3_prepare_v2(appDelegate->globalConnection,[removeKeyword UTF8String] , -1, &statement, NULL) == SQLITE_OK)
if(sqlite3_prepare_v2(appDelegate->globalConnection,query , -1, &statement, NULL) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_DONE) {
sqlite3_finalize(statement);
return YES;
}
}
return NO;
}
but it is not working, can anyone guide me please?

Is your method returning YES?
A couple of things:
Always log sqlite3_errmsg on any failures
Right now, you're only doing sqlite3_finalize is sqlite3_step returns SQLITE_DONE, whereas you really should be doing it whenever you successfully did sqlite3_prepare_v2
So, I might suggest, at a minimum:
-(BOOL) removeSegmentWithSegmentId:(NSInteger)sId
{
BOOL success = NO;
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
sqlite3_stmt *statement;
NSString *removeKeyword = [NSString stringWithFormat:#"DELETE FROM segment WHERE segment.segment_id = %d",sId];
if (sqlite3_prepare_v2(appDelegate->globalConnection, [removeKeyword UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_DONE)
{
success = YES;
}
else
{
NSLog(#"%s: step not ok: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
}
sqlite3_finalize(statement);
}
else
{
NSLog(#"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
}
return success;
}
Assuming this method was always returning YES, if you're not seeing records deleted, it must be that it's not finding a record to delete. (That is not considered a SQLite failure. The SQL was successfully executed, but the WHERE clause couldn't be satisfied.) You can verify this by defining the following method:
- (NSInteger)countSegmentWithSegmentId:(NSInteger)sId
{
NSInteger count = 0;
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
sqlite3_stmt *statement;
NSString *sql = [NSString stringWithFormat:#"SELECT segment_id FROM segment WHERE segment.segment_id = %d", sId];
if (sqlite3_prepare_v2(appDelegate->globalConnection, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
while ((rc = sqlite3_step(statement)) == SQLITE_ROW)
count++;
sqlite3_finalize(statement);
}
else
{
NSLog(#"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
return -1;
}
return count;
}
And then put the diagnostic message in removeSegmentWithSegmentId:
- (BOOL)removeSegmentWithSegmentId:(NSInteger)sId
{
BOOL success = NO;
NSInteger count = [self countSegmentWithSegmentId:sId];
NSLog(#"%s there are %d records with segment_id of %d", __FUNCTION__, count, sId);
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
sqlite3_stmt *statement;
NSString *removeKeyword = [NSString stringWithFormat:#"DELETE FROM segment WHERE segment.segment_id = %d",sId];
if (sqlite3_prepare_v2(appDelegate->globalConnection, [removeKeyword UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_DONE)
{
success = YES;
}
else
{
NSLog(#"%s: step not ok: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
}
sqlite3_finalize(statement);
}
else
{
NSLog(#"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
}
return success;
}

if(sqlite3_step(statement) == SQLITE_DONE)
{
sqlite3_finalize(statement);
return YES;
}
else
{
NSLog(#"Failed to delete row %s", sqlite3_errmsg(database));
}
check the error msg.

Please try this
Steps are
1.Open database
2.Delete row from table
3.Close database
Also added NSLog to view the error in console
//------------------------------------------------------------------------
// Method : checkAndCreateDatabase
// Method to Check and Create the database
//------------------------------------------------------------------------
//Function to check & create a database
-(void) checkAndCreateDatabase
{
//-------------------------------------------
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:cDatabasePath];
//-------------------------------------------
//databse already there
if(success)
{
return;
}
//-------------------------------------------
//create database
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:cDatabaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:cDatabasePath error:nil];
}
//------------------------------------------------------------------------
// Method : checkAndCreateDatabase
// Method to open database
//------------------------------------------------------------------------
-(void) openDatabase
{
cDatabaseName = #"db.sqlite";
NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentsPaths objectAtIndex:0];
cDatabasePath = [documentDir stringByAppendingPathComponent:cDatabaseName];
[self checkAndCreateDatabase];
//-------------------------------------------
if(sqlite3_open([cDatabasePath UTF8String],&database) == SQLITE_OK)
{
//nothing
}
}
//------------------------------------------------------------------------
// Method : closeDatabase
// Method to close database
//------------------------------------------------------------------------
- (void)closeDatabase
{
// Close the database.
if (sqlite3_close(database) != SQLITE_OK) {
//NSLog(#"Error: failed to close database with message '%s'.", sqlite3_errmsg(database));
}
}
-(BOOL) removeSegmentWithSegmentId:(NSInteger)sId
{
//for sharing variables of appdelegate file
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
BOOL isDeleted=NO;
[self openDatabase];
const char *sqlStatement;
sqlStatement = "DELETE FROM segment WHERE segment_id =?";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(appDelegate.database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
sqlite3_bind_int(compiledStatement, 1, sId);
if(SQLITE_DONE != sqlite3_step(compiledStatement))
{
NSLog( #"Error while deleting metadata of segment '%s'", sqlite3_errmsg(appDelegate.database));
}
else
{
NSLog(#"Deleted chart segment successfully !");
isDeleted=YES;
}
//-------------------------------------------
sqlite3_reset(compiledStatement);
}
else
{
NSLog( #"Error while deleting segment of chart '%s'", sqlite3_errmsg(appDelegate.database));
}
sqlite3_finalize(compiledStatement);
[self closeDatabase];
return isDeleted;
}

delete rows using name from text box.
(BOOL) deleteRow:(NSString *)name {
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
NSString *querySQL = [NSString stringWithFormat: #"DELETE FROM person WHERE name='%#'",name];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE) {
sqlite3_finalize(statement);
sqlite3_close(database);
return YES;
}
else
{
NSLog(#"%d",sqlite3_step(statement));
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}
return Yes if deleted successfully and return NO if fail to delete.

Related

Images not storing to database

I stored some images in my server. And try to get this images from URL and store to local database then try to access. But the images are not storing to database. But when i use log it displaying inserting all the values. But i can't shown in db via SQLiteManager
code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
// [overlayButton setFrame:CGRectMake(80, 420, 60, 30)];
[btn setFrame:CGRectMake(50, 50, 30, 30)];
[btn addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
Button click:
-(void)click:(id)sender{
NSLog(#"click");
NSString *databasePath=[[NSBundle mainBundle]pathForResource:#"db1" ofType:#"sqlite"];
NSError *err=nil;
NSFileManager *fm=[NSFileManager defaultManager];
NSArray *arrPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, -1);
NSString *path=[arrPaths objectAtIndex:0];
NSString *path2= [path stringByAppendingPathComponent:#"db1.sqlite"];
bool success=[fm copyItemAtPath:databasePath toPath:path2 error:&err];
if(!success){
NSLog(#"file copied successfully");
}
/*
if(![fm fileExistsAtPath:path2])
{
bool success=[fm copyItemAtPath:databasePath toPath:path2 error:&err];
if(success)
NSLog(#"file copied successfully");
else
NSLog(#"file not copied");
}
*/
NSURL *URL = [NSURL URLWithString:#"http://myserver.net/projects/mobile/jsonstring.php"];
NSError *error;
NSString *stringFromFileAtURL = [[NSString alloc]
initWithContentsOfURL:URL
encoding:NSUTF8StringEncoding
error:&error];
//NSLog(#"response is %#", stringFromFileAtURL);
// NSString *path = [documentsDirectory stringByAppendingPathComponent:#"db1.sqlite"];
//NSLog(#"filepath %#",path);
NSString *path1 = [path stringByAppendingPathComponent:#"db1.sqlite"];
//NSDictionary *jsonDict = [stringFromFileAtURL JSONValue];
//array
NSArray *userData = [stringFromFileAtURL JSONValue];
[stringFromFileAtURL release];
int i = 0;
BOOL notExist = TRUE;
sqlite3_stmt *statement, *addStmt;
for (NSArray *skarray in userData) {
//NSLog(#"test");
if(i == 0){
//insert all main category
for (NSDictionary *tuser in skarray) {
//write all this in the table
//if already exists in data base id then overwrite the name
//category table
//NSLog(#"CategoryId is %#",[tuser objectForKey:#"cat_id"]);
//NSLog(#"CategoryName is %#",[tuser objectForKey:#"cat_name"]);
if (sqlite3_open([path1 UTF8String], &database) == SQLITE_OK) {
const char *sql = [[NSString stringWithFormat:#"SELECT id FROM categories where id = '%#'",[tuser objectForKey:#"id"]] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(#"categories select is %s", sql);
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
notExist = TRUE;
while (sqlite3_step(statement) == SQLITE_ROW) {
notExist = FALSE;
}
}
if(notExist){
//NSLog(#"cat id does not exist");
const char *sqlInsert = [[NSString stringWithFormat:#"insert into categories (id,cat_name,order_by) values('%#','%#','%#')", [tuser objectForKey:#"id"], [tuser objectForKey:#"cat_name"],[tuser objectForKey:#"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(#"categories insert is %s", sqlInsert);
if(sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) == SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
if(SQLITE_DONE == sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
}
}
}
if(i == 1){
//insert all main category
for (NSDictionary *tuser in skarray) {
//write all this in the table
//if already exists in data base id then overwrite the name
//category table
//NSLog(#"CategoryId is %#",[tuser objectForKey:#"cat_id"]);
//NSLog(#"CategoryName is %#",[tuser objectForKey:#"cat_name"]);
if (sqlite3_open([path1 UTF8String], &database) == SQLITE_OK) {
const char *sql = [[NSString stringWithFormat:#"SELECT product_image FROM product where cat_id = '%#'",[tuser objectForKey:#"id"]] cStringUsingEncoding:NSUTF8StringEncoding];
// NSLog(#"product select is %s", sql);
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
notExist = TRUE;
while (sqlite3_step(statement) == SQLITE_ROW) {
notExist = FALSE;
}
}
if(notExist){
//NSLog(#"cat id does not exist");
// imgData = UIImagePNGRepresentation([tuser objectForKey:#"product_image"]);
// sqlite3_bind_blob(addStmt, 6, [imgData bytes], [imgData length], NULL);
const char *sqlInsert = [[NSString stringWithFormat:#"insert into product (id, cat_id,product_image,order_by) values ('%#','%#','%#','%#')", [tuser objectForKey:#"id"], [tuser objectForKey:#"cat_id"],[tuser objectForKey:#"product_image"],[tuser objectForKey:#"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(#"product insert %s", sqlInsert);
if(sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) == SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
if(SQLITE_DONE == sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
}
}
}
if(i == 2){
//insert all main category
for (NSDictionary *tuser in skarray) {
NSLog(#"version id is %#",[tuser objectForKey:#"product_id"]);
const char *sqlInsert = [[NSString stringWithFormat:#"insert into version_app (id) values ('%#')", [tuser objectForKey:#"product_id"]] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(#"stmt is %s", sqlInsert);
if(sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) == SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
if(SQLITE_DONE == sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
}
i++;
}
}
Do you see anything wrong here:
bool success=[fm copyItemAtPath:databasePath toPath:path2 error:&err];
if(!success){
NSLog(#"file copied successfully");
}

iOS: Sqlite database error : Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'error preparing statement'

I had used sqlite DB for my application and i need to call the two simultaneous queries, but i giving error as : Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'error preparing statement'
I am running a timer of every 10 seconds for Selecting rows from DB and Insert rows in DB after a button event.
My code snippet as:
in viewWillAppear:
int result2 = sqlite3_open([dbPath UTF8String], &database);
if (result2 != SQLITE_OK) {
NSLog(#"Failure in connecting to the database with result %d",result2);
}
else {
NSLog(# "Succesfully opened connection to DB") ;
}
and in viewWillDisappear:
int result = sqlite3_close(database);
if (result != SQLITE_OK){
NSLog(#"Failure in closing connection to database. Result %d",result);
}
else {
NSLog(#"Successfully closed DB connection") ;
}
For Inserting rows:
NSString *queryInsert = [NSString stringWithFormat: #"insert into mail_snoozlist (msgBody,msgSubject, msgSender,msgTo,msgDate,snoozTime) values('%#','%#','%#','%#','%#','%#')",strBody,msgSub,msgFrom,msgTo,strMsgDate,stringFromDate];
NSLog(#"queryInsert:%#",queryInsert);
const char *sql = [queryInsert UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_step(statement);
sqlite3_reset(statement);
} else {
NSAssert1(0,#"error preparing statement",sqlite3_errmsg(database));
return;
}
sqlite3_finalize(statement);
and for Selecting rows:
NSString *querySQL2 = [NSString stringWithFormat: #"Select * from mail_snoozlist WHERE snoozTime = '%#'",_snoozTime];
NSLog(#"querySql:%#",querySQL2);
if (sqlite3_prepare_v2(database, [querySQL2 UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
Message *obj = [[Message alloc] init];
NSString *msgBody=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
obj.msgBody= msgBody;
NSString *msgSub=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
obj.msgSub= msgSub;
NSString *msgSender=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
obj.msgFrom= msgSender;
NSString *msgTo=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
obj.msgTo= msgTo;
NSString *msgDate=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)];
obj.msgDate= msgDate;
[listOfItems addObject:obj];
[self.tableView reloadData];
}
sqlite3_reset(statement);
sqlite3_finalize(statement);
Anyone please help me to solve this problem.
Thanks!
You should change your NSAssert statement to include the error message:
NSAssert1(0, #"error preparing statement: %s", sqlite3_errmsg(database));
Once you do that, you should get a meaningful response which will help you diagnose the problem.
Without looking at the sqlite3_errmsg message, it is difficult to diagnose the problem. It could be as simple as a typo in a column name or table name or as complicated as the table not being found because the database wasn't found when it was created, so a blank database (without that table) was created. Hard to say until we see the error message.
As an aside, you should not be building your SQL with stringWithFormat because you open yourself to SQL injection attacks as well as will have problems if any of those text values have an apostrophe in them. You should use ? placeholders instead of printf-style formatters, and then bind the values to those columns with sqlite3_bind_text calls:
NSString *queryInsert = #"insert into mail_snoozlist (msgBody,msgSubject, msgSender,msgTo,msgDate,snoozTime) values(?, ?, ?, ?, ?, ?)";
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSAssert1(0,#"error preparing statement: %s",sqlite3_errmsg(database));
return;
}
// for these 6 sqlite3_bind function calls, if any of these strings can be `nil`, then you'd
// want to call sqlite3_bind_null if that's the case, rather than sqlite3_bind_text
if (sqlite3_bind_text(statement, 1, [strBody UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 1: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_bind_text(statement, 2, [msgSub UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 2: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_bind_text(statement, 3, [msgFrom UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 3: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_bind_text(statement, 4, [msgTo UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 4: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_bind_text(statement, 5, [strMsgDate UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 5: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_bind_text(statement, 6, [stringFromDate UTF8String], -1, NULL) != SQLITE_OK) {
NSAssert1(0,#"error binding 6: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_step(statement) != SQLITE_DONE) {
NSAssert1(0,#"error stepping: %s",sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
I illustrate the issue with the insert statement, but the same should be done with the select statement, too.
Add these two methods and call them in insert method before insertion and selection,
- (void) createEditableCopyOfDatabaseIfNeeded
{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"dbname.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
//{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"dbname.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
// }
if (!success)
{
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (void)initializeDatabase
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"dbname.sqlite"];
sqlite3_open([path UTF8String], &database);
}

"Database is locked" in delete operation in my sqlite

I have a function like this for delete table row in my apps, but I have an error that said "database is locked".
- (BOOL) deleteByCaption:(NSString *)registerCaption
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
NSString *querySQL = [NSString stringWithFormat:#"DELETE FROM tabelA WHERE CONTENT_CAPTION = \"%#\"", registerCaption];
const char *query_stmt = [querySQL UTF8String];
// NSMutableArray *resultArray = [[NSMutableArray alloc] init];
if(sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK){
if(sqlite3_step(statement) == SQLITE_ROW){
return YES;
}else{
NSLog(#"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
return NO;
}
}
sqlite3_reset(statement);
}
return NO;
}
You are missing sqlite3_finalize(). Look at //PUT HERE part in following code.
- (BOOL) deleteByCaption:(NSString *)registerCaption
{
BOOL isDeleted = NO; //EDIT
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
NSString *querySQL = [NSString stringWithFormat:#"DELETE FROM tabelA WHERE CONTENT_CAPTION = \"%#\"", registerCaption];
const char *query_stmt = [querySQL UTF8String];
// NSMutableArray *resultArray = [[NSMutableArray alloc] init];
if(sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK){
if(sqlite3_step(statement) == SQLITE_ROW){
isDeleted = YES;
//return YES; //EDIT
}else{
NSLog(#"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
//return NO; //EDIT
}
}
sqlite3_reset(statement);
sqlite3_finalize(statement); //PUT HERE
sqlite3_close(database); //EDIT
}
//return NO; //EDIT
return isDeleted; //EDIT
}
EDIT:
Try to set one variable to return.
Look at the edited portion in above code. Search for //EDIT.
In deleteByCaption function too, You are returning from function without closing data base.
You should write following statements before writing "RETURN YES" or "RETURN NO"
sqlite3_finalize(statement);
sqlite3_close(database);
Please check all functions where your have used sqlite3_open() function.
and make sure to write sqlite3_close() function before returning from that function.

not able to insert record in table in objective c

I made iPad application in which,
I want to insert record into database table, but I am unable to do the same.
here is my code snippet,
-(void) insertRecordIntoTableNamed: (NSString *) symbol{
NSString *sql = [NSString stringWithFormat:#"INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('%#',datetime())",symbol];
NSLog(#"sql=%#",sql);
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK)
{
sqlite3_close(db);
NSAssert(0, #"Error updating table.");
}
}
my NSLog shows:
sql=INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('PATNI',datetime())
this statement is correct, but i am unable to see VALUES PATNI and datetime() in my database table
here is rest of the code,
NSString *filePahs = Nil;
-(NSString *) filePath {
filePahs=[[NSBundle mainBundle] pathForResource:#"companymaster" ofType:#"sql"];
NSLog(#"path=%#",filePahs);
return filePahs;
}
result of above method is:
path=/Users/krunal/Library/Application Support/iPhone Simulator/5.0/Applications/9FF61238-2D1D-4CB7-8E24-9AC7CE9415BC/iStock kotak.app/companymaster.sql
-(void) openDB {
//---create database---
if (sqlite3_open([[self filePath] UTF8String], &db) != SQLITE_OK )
{
sqlite3_close(db);
NSAssert(0, #"Database failed to open.");
}
}
-(void) getAllRowsFromTableNamed: (NSString *) tableName {
//---retrieve rows---
NSString *qsql = #"SELECT * FROM recentquotes";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2( db, [qsql UTF8String], -1, &statement, nil) ==
SQLITE_OK) {
NSLog(#"b4 while");
while (sqlite3_step(statement) == SQLITE_ROW)
{
char *field1 = (char *) sqlite3_column_text(statement, 0);
NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];
[recentqotarray addObject:field1Str];
[field1Str release];
}
//---deletes the compiled statement from memory---
sqlite3_finalize(statement);
NSLog(#"recentqotarray=%#",recentqotarray);
}
}
edit
i wrote this, and when i checked my log i got like this, "in find data" , i didn't got my sql=...
- (void) finddata
{
NSString *databasePath;
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
NSLog(#"in finddata");
if (sqlite3_open(dbpath, &db) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT * FROM recentquotes"];
NSLog(#"sql=%#",querySQL);
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"Inside recent quote table");
char *field1 = (char *) sqlite3_column_text(statement, 0);
NSLog(#"Column name=%s",field1);
NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];
[recentqotarray addObject:field1Str];
NSLog(#"array=%#",recentqotarray);
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
}
}
Thanks In Advance
In your:
NSString *sql = [NSString stringWithFormat:#"INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('%#',datetime())",symbol];
Instead of '%#' try using \"%#\" , and check if it inserts into your db.
EDIT:
I've been working on DB a lot lately, and i've been able to successfully insert data in my sqlite, i'll write down what i use check if it helps:
NSArray*dirPath;
NSString*docDir;
dirPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docDir=[dirPath objectAtIndex:0];
databasePath=[docDir stringByAppendingPathComponent:#"example.sqlite"];
BOOL success;
NSFileManager*fm=[NSFileManager defaultManager];
success=[fm fileExistsAtPath:databasePath];
if(success)
{
NSLog(#"Already present");
}
NSString*bundlePath=[[NSBundle mainBundle] pathForResource:#"example" ofType:#"sqlite"];
NSError*error;
success=[fm copyItemAtPath:bundlePath toPath:databasePath error:&error];
if(success)
{
NSLog(#"Created successfully");
}
const char*dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &myDB)==SQLITE_OK)
{
NSString*insertSQL=[NSString stringWithFormat:#"insert into extable (name) values (\"%#\")",[nametextField.text]];
const char*insertStmt=[insertSQL UTF8String];
char *errmsg=nil;
if(sqlite3_exec(myDB, insertStmt, NULL, NULL, &errmsg)==SQLITE_OK)
{
NSLog(#"ADDED!");
}
sqlite3_close(myDB);
}

sqlite Constraint failed

I am developing an app based on sqlite,
When i am inserting data in to database the following error occurs.
Table Structure:
CREATE TABLE "Products" ("ProductBarcode" VARCHAR PRIMARY KEY UNIQUE NOT NULL , "ProductName" VARCHAR NOT NULL , "ProductImage" VARCHAR NOT NULL , "ProductIngredients" VARCHAR NOT NULL , "ProductStatus" VARCHAR NOT NULL )
2011-04-15 10:09:48.408 halalgauge[4517:207] Not Matched
2011-04-15 10:09:48.410 halalgauge[4517:207] *** Assertion failure in -[sqlClass addRecord:], /Users/admin/Desktop/Halal/Classes/sqlClass.m:149
2011-04-15 10:09:48.410 halalgauge[4517:207] Exception occured at add statement, the error is Error while inserting data. 'constraint failed'
The code is:
#import "sqlClass.h"
sqlite3 *database = nil;
sqlite3_stmt *deleteStmt = nil;
sqlite3_stmt *addStmt = nil;
sqlite3_stmt *detailStmt = nil;
sqlite3_stmt *updateStmt = nil;
#implementation sqlClass
#synthesize membersInfoArray,membersInfoDict,rowID;
- (void) copyDatabaseIfNeeded
{
membersInfoArray = [[NSMutableArray alloc]init];
membersInfoDict = [[NSMutableDictionary alloc]init];
//Using NSFileManager we can perform many file system operations.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"HalalGauge.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (NSString *) getDBPath {
#try {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"HalalGauge.sqlite"];
}
#catch (NSException * e) {
NSLog(#"Exception");
}
#finally {
//[sqlClass finalizeStatements];
NSLog(#"At Finally block");
}
}
+ (void) finalizeStatements {
if (addStmt) sqlite3_finalize(addStmt);
if (database) sqlite3_close(database);
if (deleteStmt) sqlite3_finalize(deleteStmt);
if (detailStmt) sqlite3_finalize(detailStmt);
if (updateStmt) sqlite3_finalize(updateStmt);
}
- (void) gettingData:(NSString *)dbPath {
NSLog(#"Data base path is %#",dbPath);
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
const char *sql = "select * from Products";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
[membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)] forKey:#"ProductBarcode"];
[membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] forKey:#"ProductName"];
[membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] forKey:#"ProductImage"];
[membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:#"ProductIngredients"];
[membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] forKey:#"ProductStatus"];
if(membersInfoDict)
{
[membersInfoArray addObject:membersInfoDict];
membersInfoDict = nil;
// NSLog(#"Entered and return");
// return;
}
}
}
}
else
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}
- (void) addRecord:(NSMutableDictionary *)recordDict
{
#try {
if(addStmt == nil) {
const char *sql = "insert into Products (ProductBarcode,ProductName,ProductImage,ProductIngredients,ProductStatus) Values(?,?,?,?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [[recordDict objectForKey:#"ProductBarcode"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [[recordDict objectForKey:#"ProductName"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 3, [[recordDict objectForKey:#"ProductImage"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 4, [[recordDict objectForKey:#"ProductIngredients"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 5, [[recordDict objectForKey:#"ProductStatus"] UTF8String], -1, SQLITE_TRANSIENT);
//NSLog(#"the values are %#",addStmt);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
rowID = sqlite3_last_insert_rowid(database);
NSLog(#"last inserted rowId = %d",rowID);
sqlite3_close(database);
}
#catch (NSException * e) {
NSLog(#"Exception occured at add statement, the error is %# ",e);
}
#finally {
[sqlClass finalizeStatements];
}
}
#end
may be it's not a "not null" constrain but "ProductBarcode" PRIMARY KEY UNIQUE?
did you check you product barcode uniqueness???
I solved my problem with the following code:
- (void) addRecord:(NSMutableDictionary *)recordDict
{
#try {
[self checkAndCreateDatabase];
if (sqlite3_open([databasePath UTF8String], &database)== SQLITE_OK) {
NSString *statement;
sqlite3_stmt *compiledstatement;
NSString *ProductName,*ProductBarcode,*ProductImage,*ProductIngredients,*ProductStatus;
ProductName = [recordDict objectForKey:#"ProductName"];
ProductBarcode = [recordDict objectForKey:#"ProductBarcode"];
ProductImage = [recordDict objectForKey:#"ProductImage"];
ProductIngredients = [recordDict objectForKey:#"ProductIngredients"];
ProductStatus = [recordDict objectForKey:#"ProductStatus"];
statement = [[NSString alloc]initWithFormat:#"insert into Products values('%#','%#','%#','%#','%#')",ProductBarcode,ProductName,ProductImage,ProductIngredients,ProductStatus];
const char *sqlstatement = [statement UTF8String];
if (sqlite3_prepare_v2(database, sqlstatement, -1, &compiledstatement, NULL)== SQLITE_OK) {
if (SQLITE_DONE!=sqlite3_step(compiledstatement) ) {
NSAssert1(0,#"Error when inserting %s",sqlite3_errmsg(database));
}
else {
NSLog(#"Data inserted Successfully");
}
sqlite3_finalize(compiledstatement);
}
sqlite3_close(database);
}
}
#catch (NSException * e) {
NSLog(#"The Record already inserted ");
}
}