I have a sqlite in my app , and everything seem to be ok , but i database method the while loop is not executed , and i can't get the result from query. Could somenone help me? Any help will be apreciate !
I also create a copy for databse, as i saw in other answer for other questions .
- (void)viewDidLoad {
[super viewDidLoad];
int sqlite3_open(const char *filename, sqlite3 **database);
sqlite3 *contactDB; //Declare a pointer to sqlite database structure
NSString *path = [[NSBundle mainBundle] pathForResource:#"verbeGeo" ofType:#"sqlite"];
if (sqlite3_open([path UTF8String], &contactDB) == SQLITE_OK)
{
NSLog(#"DB is open");
} else {
NSLog(#"DB can be open");
}
NSString *querySQL = #"select id from conjugare where rowid=1";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(contactDB, query_stmt, -1,
&statement, NULL) == SQLITE_OK)
{
NSLog(#"Statement prepared successfully");
} else {
NSLog(#"Statement preparation failed");
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
NSLog(#"%s Prepare failure '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(contactDB), sqlite3_errcode(contactDB));
}
sqlite3_step(statement);
sqlite3_finalize(statement);
[self database];
}
-(void)database{
sqlite3 *contactDB;
NSString *querySQL = #"select id from conjugare where rowid=1";
const char *query_stmt = [querySQL UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *idNumber =
[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
sqlite3_finalize(statement);
}
Your sqlite3_open statement is initializing the contactDB variable defined in viewDidLoad. The contactDB variable defined in database is local to that method and not initialized.
1) Either make contactDB an instance variable or pass it to database.
2) Check error returns for all calls (e.g. sqlite3_prepare_v2 in the database method).
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.
I have a "messages table" , and i want only to retrieve the "user ID" with his last message.
I tried to add "2 sql statements" inside each other , But it keeps on looping without stopping,
sqlite3_stmt *statement;
NSMutableArray * messages = [[NSMutableArray alloc]init];
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT DISTINCT FROMID , USERNAME from CHATCOMPLETE"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_chatDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
int userID = [[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)] integerValue];
NSString *querySQL2 = [NSString stringWithFormat:
#"SELECT MESSAGE , USERNAME from CHATCOMPLETE where FROMID=\"%d\"",userID];
const char *query_stmt2 = [querySQL2 UTF8String];
if (sqlite3_prepare_v2(_chatDB,
query_stmt2, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"LAST MESSAGE %#",[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)]);
sqlite3_reset(statement);
}
}
}
sqlite3_reset(statement);
}
}
return messages;
UPDATE:
This is the insert message
-(void)saveData:(NSString *)message toID:(int)toID fromID:(int)fromID isRead:(BOOL)read date:(NSDate *)date messageID:(int)messageID userName:(NSString*)userName
{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO CHATCOMPLETE (MESSAGE, TOID, FROMID, READ, date, MESSAGEID, USERNAME) VALUES (\"%#\", \"%d\", \"%d\", \"%c\", \"%#\", \"%d\", \"%#\")", message, toID, fromID, read, date,messageID,userName];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_chatDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"DONE");
/* status.text = #"Contact added";
name.text = #"";
address.text = #"";
phone.text = #"";*/
} else {
// status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_chatDB);
}
}
This is the query to get the last message with a given fromID:
SELECT * FROM chatting WHERE fromID=9999 ORDER BY id DESC LIMIT 1
In SQLite 3.7.11 or later, the following query will return the message with the largest date for each sender:
SELECT *, MAX(date)
FROM ChatComplete
GROUP BY FromID
There are a few issues:
You have only one sqlite3_stmt variable for your two nested queries. You want a separate sqlite3_stmt for each.
You are calling sqlite3_reset. That is only used when binding new values to ? placeholders in your prepared statement, which is not applicable here. Worse, you're calling it inside your loop.
Unrelated to the problem at hand, but for each prepared statement, don't forget to call sqlite3_finalize when done looping through the results, in order to release the memory used when preparing the statements.
Thus, you might want something like:
sqlite3_stmt *userStatement;
sqlite3_stmt *messageStatement;
int rc; // the return code
NSMutableArray * messages = [[NSMutableArray alloc]init];
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
const char *query_stmt = "SELECT DISTINCT FROMID , USERNAME from CHATCOMPLETE";
if (sqlite3_prepare_v2(_chatDB, query_stmt, -1, &userStatement, NULL) != SQLITE_OK)
{
NSLog(#"%s: prepare userStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
else
{
while ((rc = sqlite3_step(userStatement)) == SQLITE_ROW)
{
int userID = [[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)] integerValue];
const char *query_stmt2 = "SELECT MESSAGE , USERNAME from CHATCOMPLETE where FROMID=? ORDER BY timestamp DESC LIMIT 1"; // change the `ORDER BY` to use whatever field you want to sort by
if (sqlite3_prepare_v2(_chatDB, query_stmt2, -1, &messageStatement, NULL) != SQLITE_OK)
{
NSLog(#"%s: prepare messageStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
else
{
if (sqlite3_bind_int(messageStatement, 1, userID) != SQLITE_OK)
{
NSLog(#"%s: bind userID %d failed: %s", __PRETTY_FUNCTION__, userID, sqlite3_errmsg(_chatDB));
}
while ((rc = sqlite3_step(messageStatement)) == SQLITE_ROW)
{
NSLog(#"LAST MESSAGE %#",[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)]);
}
if (rc != SQLITE_DONE)
{
NSLog(#"%s: step messageStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
sqlite3_finalize(messageStatement);
}
}
if (rc != SQLITE_DONE)
{
NSLog(#"%s: step userStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
sqlite3_finalize(userStatement);
}
}
else
{
NSLog(#"%s: open %# failed", __PRETTY_FUNCTION__, _databasePath);
}
return messages;
Note, this code sample, in addition to my three points above, also:
Log errors using sqlite3_errmsg if sqlite3_prepare_v2 fails.
Added check on return codes from sqlite3_step, too, again logging sqlite3_errmsg if it fails.
Added log if sqlite3_open failed.
Use sqlite3_bind_int() rather building SQL using stringWithFormat. In this case, because userID is numeric, this isn't critical, but if ever using string values in your WHERE clauses, using the sqlite3_bind_text() function becomes critical, so I just wanted to show the pattern.
For example, look at your save routine and try saving a message that happens to have double quotation mark in it (e.g. I spoke with Bob and he says "hello" to you.). Your stringWithFormat construct will fail. If you use sqlite3_bind_text, it will solve that problem.
BTW, as you can see, when you add all of the proper validation of results, binding of values, etc., the code becomes a bit unwieldy. You might consider using FMDB, which greatly simplifies your SQLite Objective-C code.
This question already has an answer here:
When I try SQLite on iOS, INSERT and UPDATE does not work
(1 answer)
Closed 9 years ago.
This is code I'm using to insert data into table,
sqlite3 *database;
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"mobdb.sqlite"];
if(sqlite3_open([dbPath UTF8String],&database)==SQLITE_OK)
{
const char *sqlstatement = "INSERT INTO mobDetails (nMonId, nScore) VALUES (?,?)";
sqlite3_stmt *compiledstatement;
if(sqlite3_prepare_v2(database,sqlstatement , -1, &compiledstatement, NULL)==SQLITE_OK)
{
NSString * str1 =#"1";
NSString * str2 =#"12";
sqlite3_bind_int(compiledstatement, 1, [str1 integerValue]);
sqlite3_bind_int(compiledstatement, 2, [str2 integerValue]);
if(sqlite3_step(compiledstatement)==SQLITE_DONE)
{
NSLog(#"done");
}
else
{
NSLog(#"ERROR");
}
sqlite3_reset(compiledstatement);
}
else
{
NSAssert1(0, #"Error . '%s'", sqlite3_errmsg(database));
}
sqlite3_close(database);
}
Its shows "done" message but data not inserted into the table can any one help me for this.
also how to insert string in the table ?
The problem is that the app bundle is read-only (as you could have probably found out after 5 minutes of googling). Consequently, you can't insert to a database in the app bundle.
One thing that is wrong with the usage of the SQLite API is that you are calling sqlite3_reset() whereas sqlite3_finalize() should have been called. (Thanks #trojanfoe.)
(Oh, and this has absolutely nothing to do with Xcode at all.)
- (void) saveData
{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO CONTACTS
(name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
name.text, address.text, phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
status.text = #"Contact added";
name.text = #"";
address.text = #"";
phone.text = #"";
} else {
status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
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.
i have a view Controller called as VegQuantity which does totalcost=(quantity*cost of the dish) and inserts the itemname,quantity,totalcost into a table called as FINALORDER with database name FinalOrder
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &FinalOrder) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO FINALORDER (itemname, quantity, totalcost) VALUES (\"%#\", \"%#\", \"%#\")", itemName.text, input.text, output.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(FinalOrder, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
// status.text = #"Contact added";
// name.text = #"";
// address.text = #"";
// phone.text = #"";
NSLog(#"added");
} else {
NSLog(#"Couldnt add");
}
sqlite3_finalize(statement);
sqlite3_close(FinalOrder);
}
Final View Controller viewdidload method
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &FinalOrder) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT * FROM FINALORDER"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(FinalOrder, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *itemname = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
item.text = itemname;
NSString *qua = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
quantity.text = qua;
NSString *total = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
totalcost.text=total;
}
sqlite3_finalize(statement);
}
sqlite3_close(FinalOrder);
}
But i keep getting this error called expected expression before FinalOrder,and is it correct for me to write this code inside viewdidload? i dont have any button in Final view controller i have a button called order in a view controller called as Restaurant which actually shows me Final view controller..am i supposed to search for the db file again in the Final viewcontroller and i am sorry question seems kind of vague but in brief i just want to know how to retrieve and display the data which i have inserted in VegQuantity view controller into the final view controller thanks
I believe that the problem must rest in the definition of FinalOrder which, on the basis of the error message, looks like has been defined as a class, not as a sqlite3 * variable. Given that the scope of your usage of the database is limited to these two methods, I'd suggest defining a sqlite3 * within that scope, and use that, such as:
- (void)saveRecord
{
sqlite3 *database;
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
[self purgeTable:database];
NSString *insertSQL = #"INSERT INTO FINALORDER (itemname, quantity, totalcost) VALUES (?, ?, ?)";
if (sqlite3_prepare_v2(database, [insertSQL UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [itemName.text UTF8String], -1, NULL);
sqlite3_bind_int(statement, 2, [input.text intValue]);
sqlite3_bind_double(statement, 3, [output.text doubleValue]);
if (sqlite3_step(statement) == SQLITE_DONE)
{
// status.text = #"Contact added";
// name.text = #"";
// address.text = #"";
// phone.text = #"";
NSLog(#"added");
} else {
NSLog(#"%s Couldn't add; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
} else {
NSLog(#"%s Couldn't prepare; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
}
sqlite3_close(database);
}
}
Note, in addition to using a sqlite3 * variable for the database, to make this a little more robust:
I have replaced the stringWithFormat statement that built the SQL insert statement with an INSERT statement that uses the ? placeholders and then use sqlite3_bind_text to bind values to that statement. This way, if someone entered a value that included a quotation mark, the insert statement will still work (your original implementation would have crashed and/or was susceptible to a SQL injection attack).
I have also added the sqlite3_errmsg statements so if something goes wrong, I know what the problem was.
Rather than treating these three fields as text fields, I'm assuming your table is defined as CREATE TABLE IF NOT EXISTS FINALORDER (itemname TEXT, quantity INT, totalcost REAL); and therefore use text, int, and double bind statements.
This, incidentally, invokes a purgeTable method, so if you run it twice, it will remove the old record in there:
- (void)purgeTable:(sqlite3 *)database
{
if (sqlite3_exec(database, "DELETE FROM FINALORDER;", NULL, NULL, NULL) != SQLITE_OK)
NSLog(#"%s Couldn't purge table %s", __FUNCTION__, sqlite3_errmsg(database));
}
Anyway, you can then read this data via:
- (void)loadRecord
{
sqlite3 *database;
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySQL = #"SELECT * FROM FINALORDER";
if (sqlite3_prepare_v2(database, [querySQL UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *itemname = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
item.text = itemname;
//[itemname release]; // if not ARC, uncomment this line
int qua = sqlite3_column_int(statement, 1);
quantity.text = [NSString stringWithFormat:#"%1d", qua];
double total = sqlite3_column_double(statement, 2);
totalcost.text = [NSString stringWithFormat:#"%1.2f", total];
}
sqlite3_finalize(statement);
} else {
NSLog(#"%s Couldn't prepare; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
}
sqlite3_close(database);
}
}
Note,
I've added a sqlite3_errmsg log statement if the sqlite3_prepare fails, and I've retired the stringWithFormat (because you weren't formatting anything).
Given that quantity was INT and total was REAL, I'm retrieving the values using the appropriate variation of sqlite3_column_text, sqlite3_column_int, or sqlite3_column_double, as appropriate.
I infer that you're not using ARC and therefore, the [NSString alloc] must have an associated release or autorelease.
Finally, in our chat, you said that you received an error message (presumably an "Undefined Symbols" message) that said:
OBJC_CLASS_$"_FinalOrder"
This means that you are trying to use an object class of FinalOrder, but you haven't defined that class anywhere. Take a look at which .o files it's reporting this error for and look at the corresponding .m file, and look for your use of the FinalOrder class there. You clearly have a FinalOrder class interface defined somewhere, but never defined the class implementation, or, if you have one, for some reason it's not included in your target's "Compile Sources" listing, so double check it's here:
Finally, by the way, make sure your database is in the Documents folder, not trying to open a copy of the database in your project's bundle (because that's read only). If you have a copy of the database in your bundle, just check to see if you already have it in you Documents folder, and if not, copy it from the bundle to the Documents folder.