Deleted record successfully but message can't be printed - ios

I have put my code here i am not getting ,what is the issue with alert message.
NSString *deleteSQL = [NSString stringWithFormat:#"DELETE FROM FAVOURITE WHERE ID = %#", self.arrayID[[sender tag]]];
const char *delete_stmt = [deleteSQL UTF8String];
NSLog(#"insert query is %#",deleteSQL);
NSLog(#"insert statement is %s",delete_stmt);
sqlite3_prepare_v2(favouriteDB, delete_stmt, 1, &statement, NULL);
NSLog(#"akh:%d",sqlite3_prepare_v2(favouriteDB, delete_stmt, -1, &statement, NULL));
NSLog(#"akhdadsa:%d",SQLITE_DONE);
sqlite3_step(statement);
NSLog(#"this %d", sqlite3_step(statement));
if (sqlite3_step(statement)==SQLITE_DONE)
{
UIAlertView *myAlert1 = [[UIAlertView alloc]initWithTitle:#"Message"
message:#"Successfully Remove From Favourite List"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:nil];
[myAlert1 show];
}

You are calling sqlite3_step twice.
The first call deletes the record, the second one then fails.

you have executed statement twice.
sqlite3_step(statement);
NSLog(#"this %d", sqlite3_step(statement));
if (sqlite3_step(statement)==SQLITE_DONE)
It should be
//sqlite3_step(statement);//delete this line
NSLog(#"this %d", sqlite3_step(statement));
if (sqlite3_step(statement)==SQLITE_DONE)

Related

iOS SQLite Blob data is saving NULL

I am trying to insert a BLOB data of SignatureView using this code but when i actually browse the database there is null instead of data.
My signature table schema is given below.
create table sign(id integer primary key AUTOINCREMENT, image blob,invoiceid integer);
-(void)storeImageData:(NSData *)imageData withInvoiceID:(NSInteger)invoiceID{
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"database.sqlite3"];
const char *dbpath = [dbPath UTF8String];
sqlite3 *contactDB;
sqlite3_stmt *statement;
NSLog(#"%#",dbPath);
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
int invoiceIDINT = (int)invoiceID;
//
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO sign (image,invoiceid) VALUES (?,%d)", invoiceIDINT];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
sqlite3_bind_blob(statement, 2, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
sqlite3_step(statement);
} else {
const char *Error = sqlite3_errmsg(database);
NSString *error = [[NSString alloc]initWithUTF8String:Error];
UIAlertView *view = [[UIAlertView alloc]initWithTitle:#"Error2" message:[NSString stringWithFormat:#"Last inserted ID: %#",error] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[view show];
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
Always check the result of sqlite3_prepare_v2. If it fails, log the problem using sqlite3_errmsg.
Only call sqlite3_finalize if sqlite3_prepare_v2 succeeds.
You get NULL for the blob because your call to sqlite3_bind_blob is passing the wrong column index. It should be 1, not 2 since your want to bind to the first ? in your INSERT statement.
Why the inconsistency? Why do you use stringWithFormat to set the value for the invoiceid column and then use sqlite_bind_xxx for the image column? You should bind both. Never use stringWithFormat to build a query.
You call sqlite3_step twice. Only call it once and bind your values before you call it.
You appear to be writing to a database inside your app's resource bundle. You can't do that on a real device. It works in the simulator but not on real iOS devices. You need to put your database file in the Documents folder.
Given all of the above, your code should be something like this:
-(void)storeImageData:(NSData *)imageData withInvoiceID:(NSInteger)invoiceID{
// This is wrong - you need to update this to use the Documents folder
NSString *dbPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.sqlite3"];
const char *dbpath = [dbPath UTF8String];
NSLog(#"%#",dbPath);
sqlite3 *contactDB;
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
const char *insert_stmt = "INSERT INTO sign (image, invoiceid) VALUES (?, ?)";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_blob(statement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
sqlite3_bind_int(statement, 2, (int)invoiceID);
if (sqlite3_step(statement) == SQLITE_DONE) {
// Row inserted successfully
} else {
const char *Error = sqlite3_errmsg(contactDB);
NSString *error = [[NSString alloc] initWithUTF8String:Error];
UIAlertView *view = [[UIAlertView alloc] initWithTitle:#"Error2" message:[NSString stringWithFormat:#"Last inserted ID: %#",error] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[view show];
}
sqlite3_finalize(statement);
} else {
NSLog(#"Unable to prepare statement %s: %s", insert_stmt, sqlite3_errmsg(contactDB));
}
sqlite3_close(contactDB);
} else {
NSLog(#"Unable to open database at path %#: %s", dbPath, sqlite3_errmsg(contactDB));
}
}

how to check item already exits in sqlite objective c

This the my code
NSString *query1 =[NSString stringWithFormat:#"select * from table name where item_name=%#",trimmedString];
// [self.dbManager executeQuery:query1];
// -(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable
NSLog(#"q1--%#",query1);
BOOL recordExist = [self.dbManager recordExistOrNot:query1];
NSLog(#"------%d",recordExist);
if (!recordExist)
{
NSString *query;
if (self.recordIDToEdit == -1) {
query = [NSString stringWithFormat:#"insert into c values(null,'%#','%d','%d',%d)",item_name.text,a,p,c];
NSLog(#"query---%#",query);
}
// Execute the query.
[self.dbManager executeQuery:query];
// If the query was successfully executed then pop the view controller.
if (self.dbManager.affectedRows != 0) {
NSLog(#"Query was executed successfully. Affected rows = %d", self.dbManager.affectedRows);
// UIAlertView *alert=[[UIAlertView alloc]initWithTitle:Nil message:#"Successfully Added to The Cart" delegate:Nil cancelButtonTitle:#"ok" otherButtonTitles:Nil, nil];
// [alert show];
[self loadData];
}
else{
NSLog(#"Could not execute the query.");
}
}
else
{
NSLog(#"item already exits....");
}
- (BOOL)recordExistOrNot:(NSString *)query1{
sqlite3 *sqlite3Database;
NSString *databasePath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
sqlite3_stmt *compiledStatement;
BOOL recordExist=NO;
if(sqlite3_open([databasePath UTF8String], &sqlite3Database) == SQLITE_OK)
{
// sqlite3_stmt *statement;
if (sqlite3_prepare_v2(sqlite3Database,[query1 UTF8String], -1, &compiledStatement, NULL)==SQLITE_OK)
{
if (sqlite3_step(compiledStatement)==SQLITE_ROW)
{
recordExist=YES;
}
else
{
//////NSLog(#"%s,",sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
sqlite3_close(sqlite3Database);
}
}
return recordExist;
}
actually i want to be check string value in the table like "select * from table name where item_name=tea"
but this code is checking integer value but i want check string value.please help me
You are missing the single quotes in you select statement. first line.
NSString *query1 =[NSString stringWithFormat:#"select * from table name where item_name=%#",trimmedString];
to
NSString *query1 =[NSString stringWithFormat:#"select * from table name where item_name='%#'",trimmedString];
i'll assume that item_name is unique then you might be better served with doing insert or ignore.
i.e.
insert or ignore into tablename (item_name) values ('something')
thsi will ignore doing the insert if that value for your key exists

Ios Adding Value in loop in sqlite

Hey my code is very simple , i have crated a sqlite table with one column id and message.
my sqlite table is created successfully. i want to insert 5 string value in message column .my code for insert string value
- (IBAction)addTextToDatabase:(id)sender
{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &myDatabase) == SQLITE_OK) {
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO SAMPLETABLE (MESSAGE) VALUES (\"%#\")",
self.textField.text];
const char *insert_stmt = [insertSQL UTF8String];
for (int k = 0; k < 5; k++) {
sqlite3_prepare_v2(myDatabase, insert_stmt,
-1, &statement, NULL);
sqlite3_finalize(statement);
}
// sqlite3_prepare_v2(myDatabase, insert_stmt,
// -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
statusOfAddingToDB = [NSString stringWithFormat:#"Text added -- %#",
textField.text];
} else {
statusOfAddingToDB = #"Failed to add contact";
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"DB Status"
message:statusOfAddingToDB delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
// sqlite3_finalize(statement);
sqlite3_close(myDatabase);
}
}
but when i check my database only one value is added to it.please help how to achieve this?
Write sqlite3_step statement within for loop before sqlite3_finalize statement
You have to run this statement:
sqlite3_step(compiledStatement) == SQLITE_DONE
after each insertion.

Rows not updating sqlite3

The following code is suppose to update 2 columns (HoursWorked and TotalEarned) in the row where Date(Primary Key) = todays date which is stored in the string dbDate. I think my update string might be written wrong. The alert view is being triggered.
sqlite3_stmt *newstatement;
sql =[NSString stringWithFormat:#"UPDATE HourLog SET HoursWorked = '%#', TotalEarned = '%#' WHERE Date ='%#'", HoursWorked, TotalEarned, dbDate];
if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &newstatement, nil)==SQLITE_OK){
NSLog(#"details updated");
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle:#"Title"
message:#"Details Updated!"
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles: nil];
[alertDialog show];
sqlite3_step(newstatement);
}
sqlite3_finalize(newstatement);
sqlite3_close(db);
A couple of issues:
The UPDATE syntax is not correct. The individual fields being updated must be separated by a comma, not the word AND.
You probably shouldn't report that the update succeeded until you confirmed the result of sqlite3_step.
In case you're not getting a hit on your WHERE clause, I might suggest determining how many rows were updated, so you can confirm that the WHERE clause succeeded.
And, as always, report sqlite3_errmsg if your SQLite calls fail or else you're flying blind.
Thus:
sqlite3_stmt *statement;
int originalTotalCount = sqlite3_total_changes(db);
NSString *sql = [NSString stringWithFormat:#"UPDATE HourLog SET HoursWorked = %# , TotalEarned = %# WHERE Date='%#'", HoursWorked, TotalEarned, dbDate];
if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil) != SQLITE_OK) {
NSLog(#"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(db));
} else {
if (sqlite3_step(statement) != SQLITE_DONE) {
NSLog(#"%s: step failed: %s", __FUNCTION__, sqlite3_errmsg(db));
} else {
int rowsUpdated = sqlite3_total_changes(db) - originalTotalCount;
NSString *message;
if (rowsUpdated == 1)
message = #"Updated one row";
else if (rowsUpdated == 0)
message = #"No rows updated";
else
message = [NSString stringWithFormat:#"Updated %d rows", rowsUpdated]; // should never happen
NSLog(#"%#", message);
UIAlertView *alertDialog = [[UIAlertView alloc] initWithTitle:nil
message:message
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles:nil];
[alertDialog show];
}
sqlite3_finalize(statement);
}
I personally wouldn't use the single quotes around the numeric values for HoursWorked and TotalEarned. And you might consider storing the date in one of the established SQLite date formats.

SQLite database deleted all the tables [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am calling this function and removes all the data first and then insert the updated values in it. but some how all the tables are removed from database.it always shows the alertview from the code.not sure what i am dong wrong.any help will be appereciated. Thank you..
-(void)fillDate
{
filemgr=[NSFileManager defaultManager];
NSString *querySQL = #"delete from getdate";
const char *dbpath = [[appDelegate getDBPath] UTF8String];
//NSLog(#"path= %#",dbpath);
BOOL flag=FALSE;
if (sqlite3_open(dbpath, &dtdb) == SQLITE_OK)
{
//"open";
const char *query_stmt = [querySQL UTF8String];
sqlite3_prepare_v2(dtdb,query_stmt,-1,&statement,NULL);
if (sqlite3_step(statement)==SQLITE_DONE)
{
//table deleted
flag=TRUE;
}
else
{
UIAlertView *d=[[UIAlertView alloc]initWithTitle:#"Message" message:#"Your Table does not deleted" delegate:self cancelButtonTitle:#"ok" otherButtonTitles: nil];
[d show];
flag=FALSE;
}
}
else
{
//"can't open";
}
sqlite3_close(dtdb);
sqlite3_finalize(statement);
if (flag)
{
sqlite3_stmt *stmt;
const char *cdbpath=[[appDelegate getDBPath] UTF8String];
if ((sqlite3_open(cdbpath,&dtdb)==SQLITE_OK))
{
char* errorMessage;
sqlite3_exec(dtdb, "BEGIN TRANSACTION", NULL, NULL, &errorMessage);
char buffer[] = "INSERT INTO getdate(lastdate) VALUES (?1)";
sqlite3_prepare_v2(dtdb, buffer, strlen(buffer), &stmt, NULL);
// for (unsigned i = 0; i < 1; i++)
// {
// NSMutableDictionary *dict=[arrayAllEvents objectAtIndex:i];
//NSLog(#"dict:%#",dict);
sqlite3_bind_text(stmt, 1, [[df stringFromDate:[NSDate date]]UTF8String], -1, SQLITE_STATIC);
int success = sqlite3_step(stmt);
sqlite3_reset(stmt);
if (success != SQLITE_DONE)
{
//nslog(#"error: %s",sqlite3_errmsg(dtdb));
}
//nslog(#"... data created.");
// }///for
if(sqlite3_exec(dtdb, "COMMIT TRANSACTION", NULL, NULL, &errorMessage)==SQLITE_OK)
{
NSLog(#"commited Events");
}
else
{
NSLog(#"Not commited");
}
// sqlite3_exec(dtdb, "COMMIT TRANSACTION", NULL, NULL, &errorMessage);
sqlite3_finalize(stmt);
}//
}
sqlite3_close(dtdb);
}
if you have updated your database then just replace the new database with old one.delete the app and run again. your code seem to be perfect.

Resources