Passing a column name instead of index in sqlite3 - objective-c

The problem code:
NSString *query = #"SELECT Name FROM Category";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char *row =(char *)sqlite3_column_text(statement,0);
char *rowData = (char *)sqlite3_column_text(statement,1);
NSString *fieldName = [[NSString alloc] initWithUTF8String:row];
NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];
NSLog(#"%#",fieldName);
NSLog(#"%#",fieldValue);
[fieldName release];
[fieldValue release];
}
sqlite3_finalize(statement);
}
char *row =(char *)sqlite3_column_text(statement,0);
In the above code instead of 0 can't I just pass a column name?
How can I do that ?

You can't, not with the C bindings anyway. Instead, you may use this Objective-C wrapper over the standard C interface: FMDB

Related

how to retrieve sqlite column values and store in to the array in objective c?

Here is my code i am getting only the last value of the database in the array but i need the entire column values in my array...
//select the values from the db
NSString *sql = [NSString stringWithFormat:#"SELECT * FROM district_details"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK)
{
while (sqlite3_step(statement)==SQLITE_ROW)
{
char *field2 = (char *)sqlite3_column_text(statement, 1);
field2Str = [[NSString alloc]initWithUTF8String:field2];
str = [NSString stringWithFormat:#"%#", field2Str]; NSLog(#"the value from thr field1 from the district name is %#...",field2Str);
myarray =[[NSMutableArray alloc]initWithObjects:#"--select the value--",nil];
[myarray addObject:field2Str];
NSLog(#"the value of the myarray is......%#",myarray);
}
}
Initiate your array object once before you use it, if you initiate it inside while loop like you do it loses the previous added objects and takes fresh allocation inside the heap memory.
Just put this code inside viewDidLoad method and remove from while loop:
- (void)viewDidLoad {
[super viewDidLoad];
// mutable array allocation do once here
myarray =[[NSMutableArray alloc]initWithObjects:#"--select the value--",nil];
}
Now use below code to fetch entire column from data base:
//select the values from the db
NSString *sql = [NSString stringWithFormat:#"SELECT * FROM district_details"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK)
{
while (sqlite3_step(statement)==SQLITE_ROW)
{
char *field2 = (char *)sqlite3_column_text(statement, 1);
field2Str = [[NSString alloc]initWithUTF8String:field2];
// --------- myarray allocation removed from here -----------
[myarray addObject:field2Str];
NSLog(#"the value of the myarray is......%#",myarray);
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
The problem is that you are instantiating a new mutable array in ever loop of your while statement. You want to instantiate it once, before the loop, and inside the loop merely addObject.
NSString *sql = [NSString stringWithFormat:#"SELECT * FROM district_details"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {
myarray = [[NSMutableArray alloc] initWithObjects:#"--select the value--",nil];
while (sqlite3_step(statement)==SQLITE_ROW) {
char *field2 = (char *)sqlite3_column_text(statement, 1);
field2Str = [[NSString alloc] initWithUTF8String:field2];
[myarray addObject:field2Str];
}
sqlite3_finalize(statement); // remember to finalize to prevent SQLite leak
}

sqlite3_prepare_v2 failing

Could anyone explain to me why this if statement is not triggering? The database opens just fine, it's just that I can't retrieve any values from the database. Also, the table name is correct as well.
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int uniqueId = sqlite3_column_int(statement, 0);
char *nameChars = (char *) sqlite3_column_text(statement, 1);
char *addressChars = (char *) sqlite3_column_text(statement, 2);
NSString *name = [[NSString alloc] initWithUTF8String:nameChars];
NSString *address = [[NSString alloc] initWithUTF8String:addressChars];
PersonInfo *info = [[PersonInfo alloc] initWithUniqueID:uniqueId name:name address:address];
[returnArray addObject:info];
}
sqlite3_finalize(statement);
}
return returnArray;
}

call an array method

I have this method, and I am trying to call that method doing [self getUsers ObjectAtIndex:0] but compiler won't compile that line at all and says it's unknown. How do I call an array method to display all the string in it?
- (NSArray*)getUsers
{
NSArray *getUsers = [[NSArray alloc] init];
NSString *databasepath;
NSString *docsDir;
NSArray *dirPaths;
//NSString *databasePath;
//get the document directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
//build the path to the database file
databasepath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:
#"users.db"]];
const char *dbPath = [databasepath UTF8String];
sqlite3_stmt *statement;
sqlite3 *userdb;
if (sqlite3_open(dbPath, &userdb) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:#"SELECT * FROM USERS WHERE username = \"%#\"", txtUsername.text];
const char *sql_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(userdb, sql_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
char *field = (char*) sqlite3_column_text(statement, 1);
NSString *usernameField = [[NSString alloc]initWithUTF8String:field];
//NSLog(#"%#", usernameField);
getUsers = [NSArray arrayWithObject:usernameField];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(userdb);
return getUsers;
}
Use [[self getUsers] objectAtIndex:0].
If you use the latest Xcode/clang version, you can also use [self getUsers][0], since arrays now support indexing.
Consider say you had a method -(id)someMethod, and then called it like this:
id myValue = [self someMethod];
Inside someMethod, there is a return statement - whatever is to the right of the return is what will be assigned to myValue in the calling method or function.
Just call like this:
NSArray *arrAllUsers = [self getUsers]; //As getUsers is method which returns nsarray.

Comparing NSString to SQLite database field

I have these codes that retrieve value from the SQLite database and comparing it to a NSString declared in the header file.
Retrieving from database:
NSString *sql = [[NSString alloc] initWithFormat:#"SELECT TESTONE, TESTTWO, TESTTHREE, TESTFOUR FROM STUDENTS WHERE NAME='%#'",Name];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)== SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_ROW){
char *one = (char *) sqlite3_column_text(statement,0);
tOne = [[NSString alloc] initWithUTF8String:one];
char *two = (char *) sqlite3_column_text(statement,1);
tTwo = [[NSString alloc] initWithUTF8String:two];
char *three = (char *) sqlite3_column_text(statement,2);
tThree = [[NSString alloc] initWithUTF8String:three];
char *four = (char *) sqlite3_column_text(statement,3);
tFour = [[NSString alloc] initWithUTF8String:four];
}
}
Comparing string:
if(tOne == #"Yes")
{
//blablabla
}
else if(tOne == #"No")
{
//blablabla
}
It doesn't seem to go into the 'IF' at all.
I have double-checked the field in the database and its TEXT datatype.
I made a UILabel to display the tOne value and it shows "Yes".
May i know what or where went wrong during the comparison?
You can't compare strings like this, you have to use isEqualToString:
if([tOne isEqualToString:#"Yes"])
{
//blablabla
}
else if([tOne isEqualToString:#"No"])
{
//blablabla
}
You are currently comparing the address of the NSString object, not its contents. Use the compare: or isEqualToString: family of methods to compare the content of the string.
Reference.

How to call different tables in an "if and else" part of the same database in iPhone?

I have a database. It has two tables in it. I want to call one table in an if condition. How do I call the second table in the else part if the if conditions fail?
This is the code I used:
{
NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DocumentsDirectory = [Paths objectAtIndex:0];
NSString *Path = [DocumentsDirectory stringByAppendingPathComponent:#"StoreList.sqlite"];
// Open the database from the users filessytem.
if (sqlite3_open([Path UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
//*********const char *sqlStatement = "select * from Store where Zipcode ='%#'",inputTxt ;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from Store where Zipcode ='%#' or Address = '%#' or CityName = '%#'",inputTxt, inputTxt, inputTxt];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array.
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
//self.tabBarController.selectedIndex=3;
}
else {
NSLog(#"ELSE PART");
// Open the database from the user's filessytem.
if (sqlite3_open([Path UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
//*********const char *sqlStatement = "select * from Store where Zipcode ='%#'",inputTxt ;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from zipcodes where zip ='35004'"];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
}
}
}
}
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
}
I'm getting the input from the text box. When I give the correct value, which is there in the database, it is working fine, the fetch of the data is correct. If I give the wrong data in the textbox it's not working fine - the else condition fails.
How can this issue be fixed?
When going on else you open the same database again, that's not needed (and might cause some problems as well, haven't tried it). Use a BOOL when running the first (select) statement and set it to YES or NO if it fails or not. After you finish with the first statement check the BOOL value and if ==NO run the second statement.
...
BOOL success = NO;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from Store where Zipcode '%#' or Address = '%#' or CityName = '%#'",inputTxt, inputTxt, inputTxt];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK){
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
//self.tabBarController.selectedIndex=3;
success=YES;
}
}
sqlite3_finalize(compiledStatement);
if(success){
//do the else from your code
NSString *sqlStatement = [NSString stringWithFormat:#"select * from zipcodes where zip ='35004'"];
NSLog(#" Query in if :%#",sqlStatement);
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK){
// Loop through the results and add them to the feeds array
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
}
}
sqlite3_finalize(compiledStatement);
}
I haven't run it, so it might contain some bugs.