Truncate table in SQLite3 on iPhone? - iphone

I want to completely clean all the contents in a SQLite3 table in my iPhone app. My MySQL experience told me that I should use TRUNCATE. But it seems that SQLite3 doesn't support TRUNCATE (at least I got an error when preparing statement when I use the sentence TRUNCATE my_table_Name).
So I turn to DELETE FROM. Two questions: 1) Will DELETE FROM clean my table in a thorough way? 2) I tried the following code and it worked. But I highly doubted that there are unnecessary or even wrong codes in it. Can anyone help me take a look at it?
Thanks in advance.
Di
-(void)deleteAllUser {
NSString *ns_sql = [NSString stringWithFormat:#"DELETE FROM %#", [Config USER_TABLE_NAME]];
const char *sql = [ns_sql cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *statement = nil;
sqlite3* db = ...; //get the database instance
if(sqlite3_prepare_v2(db, sql, -1, &statement, nil) != SQLITE_OK) {
return;
}
//Without this line, table is not modified
int code = sqlite3_step(statement);
if (code == SQLITE_ROW) {
//Do nothing here...
}
sqlite3_finalize(statement);
}

I think
if (code == SQLITE_ROW) {
//Do nothing here...
}
this code should be like
if (code == SQLITE_DONE) {
//Do nothing here...
}
If you want to get any message then you can return YES from here and NO from else(if you change return type to BOOL from void).This can help you in showing messaeges.

Related

iPhone SQLite Crash sqlite3_last_insert_rowid or sqlite3_close.

I'm having two crashes show up in my logs using the following code to insert into my SQLite DB - the code works perfectly most of the time however clearly there is a something wrong that's causing the crash.
It crashes on either sqlite3_last_insert_rowid or sqlite3_close with EXC_BAD_ACCESS (I hold a reference to the SMSDatabase and it's in a singleton not sure why it would be deallocated) and SIGABRT (memory issue?)
- (NSInteger)query:(NSString *)query {
NSInteger lastRowID = 0;
if (sqlite3_open([self.databasePath UTF8String], &smsDatabase) == SQLITE_OK)
{
sqlite3_stmt *statement = nil;
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(smsDatabase, sql, -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE)
{
lastRowID = sqlite3_last_insert_rowid(smsDatabase);
}
}
sqlite3_finalize(statement);
}
sqlite3_close(smsDatabase);
return lastRowID;
}
Where am I going wrong?
sqlite3_close(smsDatabase); - isn't this outside your if statement, which means you are closing a database which may have never been opened ?

Update value in sqlite iphone sdk

I have a simple program that update a record of a table
The table is "person" with two columns "name" and "age";
some records have been inserted, as follows:
name age
tom 20
andy 30
han 25
Now I am writing a program to update a row in the table:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *text=#"andy";
NSString *query=[NSString stringWithFormat:#"UPDATE person SET age=%d WHERE name='%#'",30,text];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query UTF8String],-1,&statement,NULL);
sqlite3_finalize(statement);
sqlite3_close(contactDB);
The program works fine, but the database is not updated (I am using SQLite Manager to browser the database)
When I try reading from database, it works well:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *query1=[NSString stringWithFormat:#"SELECT * FROM person WHERE age=%d;",30];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query1 UTF8String],-1,&statement,NULL);
sqlite3_step(statement);
NSString *result=[[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
label.text=result;
sqlite3_finalize(statement);
sqlite3_close(contactDB);
-(void)updateSetting:(NSArray *)arr
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
sqlite3_stmt *compiledStmt;
NSString *sqlStmt=[NSString stringWithFormat:#"UPDATE setting SET flow='%#',formate='%#' WHERE primaryKey=%i;",[arr objectAtIndex:0],[arr objectAtIndex:1],1];
if(sqlite3_prepare_v2(myDatabase, [sqlStmt UTF8String],-1,&compiledStmt, NULL)==SQLITE_OK)
{
NSLog(#"Successful update");
}
sqlite3_step(compiledStmt);
sqlite3_close(myDatabase);
}
}
I already faced this issues. Whats the problem behind this is you passed the query as a string format so you have to use the ; at the end of the query statement.
NSString *query=[NSString stringWithFormat:#"UPDATE questionbank SET age=%d WHERE name='%#';",30,text];
Please make a checking like below before you perform your sqlite3_step method.
const char *sqlQuery = "UPDATE SETTINGS SET someFlag = 0";
sqlite3_stmt *insertStatement = nil;
int success = 0;
if(sqlite3_prepare_v2(sqliteDatabase, sqlQuery, -1, &insertStatement, NULL) == SQLITE_OK)
{
success = sqlite3_step(insertStatement);
if(insertStatement)
{
sqlite3_finalize(insertStatement);
}
if(success == SQLITE_ERROR)
{
return NO;
}
return YES;
}
return NO;
So that you can figure out, where the problem is.
You need to check whether you could access and open the database or not. Simply place your update segment in a if-statement like this: if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK).
Also try to add NSLog(#"%s", sqlite3_errmsg(database)); after your prepare to see if there was any errors.
The answer for this problem is that the database in the main bundle is read-only
I can not insert data into sqlite3 file on XCode

How can I query a sqlite database using objective c?

I'm trying to display food by type to a user. The different types of foods are different elements in a table (fruits, veggies, meats, etc). I have all the foods in one database using sqlite. How can I query this database using objective c so that I can display only the correct type of food the user selected in the next view's table?
We use FMDB in two apps. It works fine.
-(NSArray *)GetAllFoods
{
NSMutableArray *filesArray = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
NSString *DBPath = [ClsCommonFunctions GetDatabasePath];
if ([self OpenDBWithPath:DBPath])
{
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "your query";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(filesDB, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Need to get data from database...
NSSstring *foodObj = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)]
[filesArray addObject:foodObj];
FileObj = nil;
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
sqlite3_close(filesDB);
}
return filesArray;

SQLite3 database not showing entries on console via NSLog (Saving data to the DB works)

Working on a simple TimeTracker App. You start a timer, wait a certain time, stop the clock and save spent minutes to a SQLite3 database. All is working as expected, when I tap on save I get a confirmation that record was saved but I can't get the saved entries shown on the console. As seen in the screenshot below I have a show button which should show me all my saved entries in the console including timestamp but nothing happens when I tap the button.
I think the problem is related to the search query but I can't figure our whats wrong.
From my understanding the query is looking for the timestamp (column 0) and the spent minutes (column 1) but it doesn't work, please help.
NSLog(#"Timestamp: %s - Timing: %s", sqlite3_column_text(statement, 0), sqlite3_column_text(statement, 1));
SQLite database is really simple, I only want to save one value > spent minutes.
Maybe the database is not created correctly??
Database Creation:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc]initWithString:[docsDir stringByAppendingPathComponent:#"timings.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:databasePath] == NO)
{
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open(dbPath, &timings) == SQLITE_OK)
{
char *errormsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS TIMINGS(ID INTEGER PRIMARY KEY AUTOINCREMENT, TIME INTEGER)";
if (sqlite3_exec(timings, sql_stmt, NULL, NULL, &errormsg) != SQLITE_OK)
{
self.statusLabel.text = #"Failed to create database";
}
sqlite3_close(timings);
}
else
{
self.statusLabel.text = #"Failed to open/create database.";
}
}
}
Show saved entries on console:
-(IBAction)showButton:(id)sender
{
if (sqlite3_open([databasePath UTF8String], &timings) == SQLITE_OK)
{
NSString *queryStatement = [NSString stringWithFormat:#"SELECT TIMESTAMP, TIME FROM TIMINGS"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(timings, [queryStatement UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW) {
NSLog(#"Timestamp: %s - Timing: %s", sqlite3_column_text(statement, 0), sqlite3_column_text(statement, 1));
}
sqlite3_finalize(statement);
sqlite3_close(timings);
}
}
}
Put NSLog(#"Error. '%s'", sqlite3_errmsg(database)); after each database operation completed. (ie; after, sqlite3_step, sqlite3_prepare etc). When you get data base, which was created by simulator, from Library/ApplicationSupport ....., you can open that using terminal and see the contents. Or using SQLite Manager plug in of mozilla you can open database and see contents graphically.
Do any rows get returned from your query? Open your sqlite database using a browser (http://sqlitebrowser.sourceforge.net/) and check the data is actually being saved.
Then rerun your sql in the browser to test the query, and finally put a breakpoint on
-(IBAction)showButton:(id)sender and step thru
a friend of mine just realized that I made a big mistake, I totally forgot to CREATE the column 'TIMESTAMP' I'm trying to read out here. If you look at this line: "CREATE TABLE IF NOT EXISTS TIMINGS(ID INTEGER PRIMARY KEY AUTOINCREMENT, TIME INTEGER)"; You see that I have not created the timestamp column. Last but not least is TIMESTAMP a protected keyword in SQL you are not allowed to use. To save a timestamp I just created and renamed the column and now it's working. Thanks for all your help.

check if row updated or not in sqlite?

I am using sqlite database in my iphone app.
I am writing code for update record on certain condition. While my query is correct how can I detect that any row is updated or not..
I had tried SQLITE_DONE but it shows that query executed or not... What to use..
Here is my code..
const char *sqlStmt = [strQuery UTF8String];
if (sqlite3_prepare_v2(database, sqlStmt, -1, &compiledStatement, NULL) == SQLITE_OK) {
isSucceed = sqlite3_step(compiledStatement) == SQLITE_DONE;
//isSucceed = YES;
}
what will be in place SQLITE_DONE
I think you're looking for sqlite3_changes().