Sqlite update does not effect - objective-c

My update database query did not work. I search and read many topics but did not find the solution. Also I have a delete statement and it is working smoothly.
My code:
//Checking for any previously open connection which was not closed
[self closeAnyOpenConnection];
//SqLite query
NSString *fetchQuery = [NSString stringWithFormat:#"Update Category Set CatOrder = '%d' where CatOrder = '%d'", withToIndex + 1, withFromIndex + 1];
const char *updateQuery = [fetchQuery UTF8String];
sqlite3_stmt *sqlStatement = nil;
if(sqlite3_prepare_v2(databaseReference, updateQuery, -1, &sqlStatement, NULL) == SQLITE_OK)
{
// executes the sql statement with the data you need to update in the db
sqlite3_step(sqlStatement);
// clearing the sql statement
sqlite3_finalize(sqlStatement);
//closing the database after the query execution
sqlite3_close(databaseReference);

Related

sqlite fetch statement

Good day,
I need to fetch rows from my sqlite table, but I need to pass multiple parameters. This is my statement that does not work.
SELECT * FROM messages WHERE currentuser=\"%#\" AND (belongstouser=\"%#\" OR mymsgforuser=\"%#\") ORDER BY ID ASC
I need it to first check for the currentuser match, then out of those matches to check for either the belongstouser or mymsgforuser matches. Is it possible to nest a sqlite statement in this fashion? I tried removing the parenthesis and that didn't work either. I also searched the sqlite documentation and could not find a solution.
I can see wrong SQL syntax. string constants must be quoted with single quotes (') instead of (")
And as rmaddy said, you'd better avoid stringWithFormat. Use prepare statement technique.
- (BOOL)_prepareStatement:(sqlite3_stmt **)statement withSQL:(const char *)sql {
sqlite3_stmt *s = *statement;
//caDatabase is declared as sqlite3 *caDatabase object
if (nil == s && sqlite3_prepare_v2(caDatabase, sql, -1, &s, NULL)!= SQLITE_OK)
{
[self _showError];
*statement = nil;
return NO;
}
*statement = s;
return YES;
}
- (caObjectId)existObject:(caObjectId)objId withType:(caCacheObjectType)objType libraryID:(int)aLibraryID
{
#synchronized (self)
{
const char *caSQLexistObj = "SELECT id FROM objects WHERE objId = ? AND objType = ? AND libraryID = ?";
if(![self _prepareStatement:&ca_existObjectStatement withSQL:caSQLexistObj]) {
//produce some error message
return;
}
sqlite3_bind_int(ca_existObjectStatement, 1, objId);
sqlite3_bind_int(ca_existObjectStatement, 2, objType);
sqlite3_bind_int(ca_existObjectStatement, 3, aLibraryID);
NSInteger result = sqlite3_step(ca_existObjectStatement);
if (result != SQLITE_ROW)
{
sqlite3_reset(ca_existObjectStatement);
return caObjectIdNone;
}
caObjectId cacheId = sqlite3_column_int(ca_existObjectStatement, 0);
sqlite3_reset(ca_existObjectStatement);
return cacheId;
}
}

Objective C: SQLite where-statement wont work when running another method first

So basically I have an app that will provide tasks based on selected project. Both projects and tasks are stored in a SQLite database.
To get the current project id I compare the selected project (_selectedProject) to my database, to get the ID. This is done in my getSelectedProjectId method. However, when running this method in the getTasks method, the Where-statement wont work at all. If I don't run the getSelectedProjectId method first, it works just fine. Am I forgetting to release something? Or is it something else? Any ideas?
I'm pretty new to both SQLite and Objective C, so this may not be a complex issue. I have made sure the getSelectedProjectId method returns the correct project ID. I have also made sure the query that is run in the getTasks method is correct, and when running it through my terminal it returns a number of rows. In the app it returns nothing, provided I'm running the getSelectedProjectId somewhere in that method first.
This is the method that fetches the tasks:
- (void)getTasks
{
[self openDB];
sqlite3_stmt *statement;
int projectId = [self getSelectedProjectId];
NSString *query = [NSString stringWithFormat:#"SELECT * FROM tasks WHERE project_id=%i", projectId];
const char *query_statement = [query UTF8String];
sqlite3_prepare_v2(_contactDB, query_statement, -1, &statement, NULL);
while (sqlite3_step(statement) == SQLITE_ROW)
{
// I add the task title to my array of tasks here.
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
And this is the method that gets the correct project id from the database:
- (int)getSelectedProjectId
{
sqlite3_stmt *statement;
NSString *query = [[NSString alloc]
initWithFormat:#"SELECT id FROM projects WHERE title=\"%#\" LIMIT 0,1",
_selectedProject];
int rowId = 0;
const char *query_statement = [query UTF8String];
[self openDB];
sqlite3_prepare_v2(_contactDB, query_statement, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_ROW)
{
rowId = sqlite3_column_int(statement, 0);
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
return rowId;
}
The problem occured because I closed the DB connection in my getSelectedProjectId-method. I'm now leaving my DB open instead, works like a charm.

How to execute this sqlite instruccions from code?

I need to export the information of my database to a csv file. I already know how to do that in sqlite but i need to do it from the code of an ios aplication.
I have to execute this from code.
.separator ,
.mode csv
.output test.csv
select * from tbl1;
.output stdout
I mean those arenĀ“t instructions like inserts or updates or deletes or selects...(well only one)
I tried something like this:
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_bdcontact) == SQLITE_OK) {
NSString *querySQLite = #".separator ,";
const char *querySQLite_stmt = [querySQLite UTF8String];
sqlite3_prepare_v2(_bdcontact, querySQLite_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
NSLog(#"Did what i need and just repeat this with the other instructions!");
}
sqlite3_finalize(statement);
sqlite3_close(_bdcontact);
}
I have already done instructions like selects, inserts, updates and deletes in other parts of the application so the problem is when i try to do sqlite pure instructions.
Can You help me Please?

sqlite3 COUNT in iOS (specifically ON the iPhone/iPad)

I know that the simulator and the actual iOS hardware are not EXACTLY the same, but I'm starting to pull my hair out over this one. I have this code:
sqlite3 *database;
sqlite3_stmt *statement;
int themeCount;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSString *updateSQL = [NSString stringWithFormat: #"SELECT COUNT(*) FROM Theme"];
const char *update_stmt = [updateSQL UTF8String];
if(sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL) == SQLITE_OK){
if(sqlite3_step(statement)==SQLITE_ROW)
{
themeCount = sqlite3_column_int(statement, 0);
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
With the simulator, it works perfectly fine. Once I push it to my devices, it fails. I've broken it down and came up with the return code where it fails:
if(sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL) == SQLITE_OK)
If I change that line to capture the code (ie. int x = sqlite3_prepare_v2(...)) it returns 0 with the simulator, 1 with the device. What am I doing wrong here?!?!
Also, for the record, the CREATE statement for the Theme table is:
#"CREATE TABLE Theme (ThemeId INTEGER PRIMARY KEY, ThemeName TEXT, Available BIT);"
(My first thought is that it was case sensitive)
You are not opening the database you think you are opening. The sqlite3_prepare_v2 is the first statement that needs the schema to be present. I suspect your databasePath is incorrect.
You can be more specific with sqlite3_open_v2 by omitting the SQLITE_OPEN_CREATE flag which is the default with sqlite3_open so you don't notice that a new database is being created by the open call. See SQLite3 docs. With the result of
sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READWRITE, NULL)
you will see that the database does not exist.

Getting number of rows from SQLite C interface in Objective-C

I am new to objective-C and iphone apps.
I am accessing SQLite and have 3 rows in my table "coffee". I used the following way to grab sth out from the table, however, only then 2nd and 3rd rows are being pulled out {the 1st row is always missed}. Is that due to the logic in my while loop by checking while sqlite3_step(selectstmt) returns SQLITE_ROW is wrong? Here is the code:
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "select coffeeID, coffeeName from coffee";
sqlite3_stmt *selectstmt;
NSLog(#"sqlite_prepare_v2 returns: %i", sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL));
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"sqlite3_step returns: %i", sqlite3_step(selectstmt));
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];
coffeeObj.coffeeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
NSLog(#"this is the coffee name: %#", coffeeObj.coffeeName);
coffeeObj.isDirty = NO;
[appDelegate.coffeeArray addObject:coffeeObj];
[coffeeObj release];
}
}
}
On the other hand, is there any convenient way for me to check the number of rows returen in a query directly from the C interface of SQLite?
Many thanks.
You could use the query SELECT COUNT(*) FROM coffee to tell you how many rows there are.
And also, save yourself some headaches and use a SQLite wrapper.
Are the 2 sqlite3_step() calls meant to be executed here?
NSLog(#"sqlite3_step returns: %i", sqlite3_step(selectstmt));
while(sqlite3_step(selectstmt) == SQLITE_ROW {
BTW: there a parenthesis missing in the while line. Do not rewrite your code for SO. Copy/Paste it to avoid copying errors (pasting errors are much more rare)