Loading data from database into detailed view - iphone

I'm reading data from a sqlite database however in my detailed view one of the data items is not showing correctly. It show what looks like random memory i.e. UIDeviceRGB...(I have two strings, one that works one that doesn't). I can't work out why but when I run the debug it returns null.
Here is my code in HydratedDetailData:
if (SQLITE_DONE != sqlite3_step(detailStmt)) {
double add = sqlite3_column_double(detailStmt, 2);
NSString *address = [NSString stringWithFormat:#"%#", add];
self.ClubAddress = address;
[address release];
}
Any help work be greatly appreciated!
code from Clubs.m
#import "Clubs.h"
static sqlite3 *database = nil;
static sqlite3_stmt *detailStmt = nil;
#implementation Clubs
#synthesize clubID, clubName, ClubAddress, isDirty, isDetailViewHydrated;
+(void) getInitialDataToDisplay:(NSString *)dbPath {
SQLAppDelegate *appDelegate = (SQLAppDelegate *) [[UIApplication sharedApplication] delegate];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "select clubID, clubName from clubNames";
sqlite3_stmt *selectstmt;
if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while (sqlite3_step(selectstmt)== SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Clubs *clubObj = [[Clubs alloc] initWithPrimaryKey:primaryKey];
clubObj.clubName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
clubObj.isDirty = NO;
[appDelegate.clubArray addObject:clubObj];
[clubObj release];
}
}
}
else
sqlite3_close(database);
}
+(void) finalizeStatements {
if (database) sqlite3_close(database);
}
-(id) initWithPrimaryKey:(NSInteger) pk {
[super init];
clubID = pk;
isDetailViewHydrated = NO;
return self;
}
-(void) hydrateDetailViewData {
if (isDetailViewHydrated) return;
if (detailStmt == nil) {
const char *sql = "Select ClubAddress from clubNames Where clubID = ?";
if (sqlite3_prepare_v2(database, sql, -1, &detailStmt, NULL) !=SQLITE_OK)
NSAssert1(0, #"Error while creating detail view statment. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_int(detailStmt, 1, clubID);
if (SQLITE_DONE != sqlite3_step(detailStmt)) {
double add = sqlite3_column_double(detailStmt, 0);
NSString *address = [NSString stringWithFormat:#"%d", add];
self.ClubAddress = address;
}
else
NSAssert1(0, #"Error while getting the address of club. '%s'", sqlite3_errmsg(database));
sqlite3_reset(detailStmt);
isDetailViewHydrated = YES;
}
-(void) dealloc {
[ClubAddress release];
[clubName release];
[super dealloc];
}
#end

i had such a problem for reading double values, some of values read right but some read as 0 ! i have tried many things but at last my problem was solved by defining variables globally. i have defined the locally in .m file but the solution was to define them in .h file.i hope it can solve yours too.
good luck

Perhaps if you used the %d formatter in your [NSString stringWithFormat:#"%#", add]; call.
(%# is generally for strings, %d is for doubles)
After our little discussion-athon, this should fix what ails you.
if (SQLITE_DONE != sqlite3_step(detailStmt)) {
char *db_text = sqlite3_column_text(detailStmt, 2);
NSString *address = [NSString stringWithUTF8String: db_text];
self.ClubAddress = address;
}
This will pull the text value from the database and convert it into an NSString*. (hopefully)....

Related

Can't select rows after inserting into database

i've got a Problem when i try to get data from the Database after inserting some data. I can't select any row from the database.
There are entries in the database but i can not get any result.
I comment out this line in AppDelegate::application:didFinishWithOptions
[dbAccess importWithDelegate:result];
and everything works just fine. But i can't find a solution to this problem.
I hope you can help me.
DatabaseAccess-Class.
#import "KejithDatabaseAccess.h"
#import "KejithEntryQueryDelegate.h"
#interface KejithDatabaseAccess (){
sqlite3 *db;
NSString *writableDatabase;
sqlite3_stmt *statement;
}
#end
#implementation KejithDatabaseAccess
-(id)init
{
if((self = [super init]))
{
// initialize database and store in _db
}
return self;
}
-(void)initializeDatabase
{
[self createEditableDatabase];
// open the database connection
if(sqlite3_open([writableDatabase UTF8String], &db) == SQLITE_OK){
NSLog(#"Database: Connection was opened successfully");
} else {
// if something went wrong clean everything up
sqlite3_close(db);
NSAssert1(0, #"Database: Failed to open database connection. Error: '%s'", sqlite3_errmsg(db));
}
}
-(void)closeDatabase
{
if(sqlite3_close(db) != SQLITE_OK){
NSAssert1(0, #"Database: Failed to close database connection. Error: '%s'", sqlite3_errmsg(db));
}
}
-(void)createEditableDatabase
{
BOOL success;
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
// create writable database and store path for later use
writableDatabase = [documentsDir stringByAppendingPathComponent:#"main-rw.db"];
success = [fileManager fileExistsAtPath: writableDatabase];
// if writable database already exists return
if(success) return;
// the editable database does not exist
// copy the default DB to the application
// documents directory
NSString *defaultPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"main.db"];
success = [fileManager copyItemAtPath:defaultPath toPath:writableDatabase error:&error];
if(!success){
NSAssert1(0, #"Database: Failed to create writable database file: '%#'.", [error localizedDescription]);
}
}
-(NSMutableArray *)queryWithDelegate
{
[self initializeDatabase];
// do we have an delegate?
if(![self delegate])
return nil;
NSMutableArray *result = [[self delegate] query:db];
[self closeDatabase];
return result;
}
-(void)importWithDelegate:(NSMutableArray *)collection
{
[self initializeDatabase];
[[self delegate] import:collection into:db];
sqlite3_finalize(statement);
[self closeDatabase];
}
-(sqlite3 *)getWritableDatabase
{
return db;
}
#end
Database Delegate-Class
#import "KejithEntryQueryDelegate.h"
#import "KejithEntry.h"
#interface KejithEntryQueryDelegate ()
#property sqlite3 *database;
#end
#implementation KejithEntryQueryDelegate
#synthesize sql;
#synthesize statement;
-(id)init
{
if((self = [super init])){
[self initSQL];
}
return self;
}
-(void)initSQL
{
sql = "SELECT _id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website FROM entry";
}
-(NSMutableArray *)query:(sqlite3 *)database
{
// store database
[self setDatabase:database];
// initialize array to store found objects
NSMutableArray *entries = [[NSMutableArray alloc] init];
// prepare sql statement
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult == SQLITE_OK){
while(sqlite3_step(statement) == SQLITE_ROW){
// allocate object to store row
KejithEntry *entry = [[KejithEntry alloc] init];
// get data from columns
NSMutableString *title = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 1)]];
NSMutableString *description = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 2)]];
NSMutableString *phone = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 3)]];
NSMutableString *fax = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 4)]];
NSMutableString *email = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 5)]];
NSMutableString *website = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 5)]];
// set data in object
[entry setId:[NSNumber numberWithInt: sqlite3_column_int(statement, 0)]];
[entry setTitle:title];
[entry setDescription:description];
[entry setPhone:phone];
[entry setFax:fax];
[entry setEmail:email];
[entry setWebsite:website];
// put object into array
[entries addObject:entry];
}
// finalize the statement to release its resources
sqlite3_finalize(statement);
} else {
// log errors
NSLog(#"Database: Problem Occured in KejithEntryQueryDelegate.m");
NSLog(#"Database: Result Code: %d", sqlResult);
NSLog(#"Database: SQL-Error: %s", sqlite3_errmsg(database));
}
return entries;
}
-(void)import:(NSMutableArray *)collection into:(sqlite3 *)database
{
if([collection count] == 0)
return;
for(KejithEntry *entry in collection){
[self importEntry:entry into:database];
}
}
-(void)importEntry:(KejithEntry *)entry into:(sqlite3 *)database
{
sql = "INSERT INTO entry (entry_id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website, enty_latitude, entry_longitude, entry_category_id) \
VALUES \
(0,?,?,?,?,?,?,0,0,0);";
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [[entry title] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[entry getDescription] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[entry phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 4, [[entry fax] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 5, [[entry email] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 6, [[entry website] UTF8String], -1, SQLITE_STATIC);
if(sqlite3_step(statement) != SQLITE_DONE){
NSLog(#">> Database: Failed to insert into Database");
NSLog(#"SQL Error Message: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
#end
AppDelegate::application:didFinishWithLaunchingOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// create delegate for entry xml parsing
id delegate = [[KejithEntryXmlDelegate alloc] init];
KejithXmlParser *parser = [[KejithXmlParser alloc] initWithUrl:[[NSURL alloc] initWithString:entryXmlUrl]];
KejithDatabaseAccess *dbAccess = [[KejithDatabaseAccess alloc] init];
KejithEntryQueryDelegate *dbEntryDelegate = [[KejithEntryQueryDelegate alloc] init];
// set delegate to parse xml file
[parser setDelegate:delegate];
// set delegate to query data to/from database
[dbAccess setDelegate:dbEntryDelegate];
// get results of xml parsing
NSMutableArray *result = [parser parse];
NSLog(#"Count of ParseResult: %d", [result count]);
[dbAccess importWithDelegate:result];
NSLog(#"Count of DatabaseResult: %d", [[dbAccess queryWithDelegate] count]);
return YES;
}
Console-Output without [dbAccess importWithDelegate:result] commented out:
2013-12-08 15:59:44.035 staedteApp[30202:70b] Database: Connection was opened successfully
2013-12-08 15:59:44.048 staedteApp[30202:70b] Database: Connection was opened successfully
2013-12-08 15:59:44.049 staedteApp[30202:70b] Count of DatabaseResult: 0
Console-Output with [dbAccess importWithDelegate:result] commented out:
2013-12-08 16:17:18.084 staedteApp[30267:70b] Database: Connection was opened successfully
2013-12-08 16:17:18.091 staedteApp[30267:70b] Count of DatabaseResult: 50
EDIT #1 -----
Updated KejithEntryQueryDelegate::importEntry:into
-(void)importEntry:(KejithEntry *)entry into:(sqlite3 *)database
{
sql = "INSERT INTO entry (entry_id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website, enty_latitude, entry_longitude, entry_category_id) \
VALUES \
(0,?,?,?,?,?,?,0,0,0);";
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult != SQLITE_DONE){
sqlite3_bind_text(statement, 1, [[entry title] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[entry getDescription] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[entry phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 4, [[entry fax] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 5, [[entry email] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 6, [[entry website] UTF8String], -1, SQLITE_STATIC);
int sqlStepResult;
if((sqlStepResult = sqlite3_step(statement)) != SQLITE_DONE){
NSLog(#">> Database: Failed to insert into Database");
NSLog(#"SQL Error Message: %s", sqlite3_errmsg(database));
NSLog(#"SQL Step Result: %d", sqlStepResult);
}
} else {
NSLog(#"Database: Problem Occured in KejithEntryQueryDelegate.m step");
NSLog(#"Database: Result Code: %d", sqlResult);
NSLog(#"Database: SQL-Error: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
The issue is that you're using an instance variable for sql, setting it to the SELECT statement when you create KejithEntryQueryDelegate, changing it to an INSERT statement in the importEntry:into: method, but when you call query:, even though the code clearly assumes it should be SELECT statement, the sql is still the INSERT statement.
By looking at the result code of sqlite3_step (point 3, below) one can quickly identify the issue. Since sqlResult != DONE, you want to log the issue and it reports "entry.entry_title may not be NULL" (which doesn't make sense in a SELECT statement, which made me realize that the old INSERT statement was still in the sql variable).
My original answer, based upon a glance at the code is below. Point #3 is the critical observation.
Just looking at the code, I don't see anything that would obviously cause the behavior you describe. If I follow you correctly, you're saying that if you do not import data, 50 records are found, but if you do attempt to import the data, not only do you not see new data, but suddenly nothing is found (including the records that were already there). Is that really what you're saying? That's curious behavior. If this is, in fact, the issue, that would lead me to suspect that the attempt to import is causing the subsequent attempt to read to fail.
The only obvious SQLite issue here is that importWithDelegate should not be calling sqlite3_finalize. I don't even see why KejithDatabaseAccess has a sqlite3_stmt, as you don't prepare any statements in that class. Perhaps calling sqlite3_finalize with some invalid sqlite3_stmt causes problems?
There are a few minor things here:
The importEntry:into: should presumably check the result of sqlite3_prepare_v2 statement. Elsewhere, you confirm that the prepare succeeded before proceeding, but not here.
The query method is storing the email address into the web site property.
I'd also save the result of sqlite3_step in the query method so that you could check for errors, e.g.:
while((sqlResult = sqlite3_step(statement)) == SQLITE_ROW) {
// do all of your updating of entries here
}
if (sqlResult != SQLITE_DONE) {
NSLog(#"Database: Problem Occured in KejithEntryQueryDelegate.m step");
NSLog(#"Database: Result Code: %d", sqlResult);
NSLog(#"Database: SQL-Error: %s", sqlite3_errmsg(database));
}
Right now, if your sqlite3_step method failed, you'd never know.

Database not updating

I am working with database.When i am updating my fields for the first time database is updating.But when i try to update for the next time its not updating but it showing database is updating.Can i know where the problem is.Thanks!
-(void) updateData {
sqlite3_stmt *statement;
details = [updateArray objectAtIndex:0];
NSString *destinationPath = [self getDestinationPath];
const char *dbpath = [destinationPath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *updateSQL = [NSString stringWithFormat: #"UPDATE BirthdayRemainderList SET FirstName=\"%#\", LastName=\"%#\",Dob=\"%#\",Address=\"%#\",City=\"%#\",State=\"%#\",Email=\"%#\",Phone=\"%#\" WHERE ids=%#",details.firstNameString,details.lastNameString,details.dobString,details.addressString,details.cityString,details.stateString,details.emailString,details.PhoneString,details.ids];
const char *insert_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Row updated");
}
else {
NSLog(#"Failed to update row");
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
My Update Code goes here
-(IBAction) update
{
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
savedData = [[DetailsClass alloc] init];
savedData.firstNameString = firstName.text;
savedData.lastNameString = lastName.text;
NSLog(#"last name is %#",savedData.lastNameString);
savedData.dobString = dob.text;
savedData.addressString = address.text;
savedData.cityString = city.text ;
NSLog(#"Changed city value is %#",savedData.cityString);
savedData.stateString = state.text;
savedData.emailString = email.text;
NSLog(#"Changes state value is %#",savedData.emailString);
savedData.PhoneString = phone.text;
NSLog(#"Phone no is %#",savedData.PhoneString);
savedData.ids = idString;
NSLog(#"details in id %#",savedData.ids);
[delegate.updateArray addObject:savedData];
[delegate updateData];
}
Will this make any mistake
If we use two different arrays for saving and updating it will make any difference?
Let me know where the Problem is.Thanks!
Add sqlite error message to get more insight of the real problem.
sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Row updated");
}
else {
NSLog(#"Failed to update row %s", sqlite3_errmsg(database));
}
If sql db is busy somehow it would happen. Make sure you close the db if you have opened in some where else like firefox's addon.

SQLite suddenly not responding in iPhone app

I have a massive problem with SQLite in my iPhone app, that needs to be fixed for a client soon! Basically i'm pulling a column from a database and loading it into a table view on viewWillAppear. It works fine, for the first few times the view is loaded but then suddenly it starts return empty (null) values. Upon inspection it appears that there is an issue with opening the database maybe but this is my first SQLite project so it's hard to figure out what's going on.
Here is the code I use to pull the SQL information:
+ (void) getInitialDataToDisplay:(NSString *)dbPath {
NSLog(#"INCOME CALLED 1");
NavTabAppDelegate *appDelegate = (NavTabAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.incomeArray = [[NSMutableArray alloc] init];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSLog(#"INCOME CALLED 2");
const char *sql = "select IncomeID, IncomeName from Income ORDER BY IncomeName asc";
//const char *sql2 = "select categoryID, Size from coffee";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"INCOME CALLED 3");
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSLog(#"INCOME CALLED 4");
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Income *incomeObj = [[Income alloc] initWithPrimaryKey:primaryKey];
//This is how I pull info from the database using the above select statement and setting it in the coffeeObj property of Coffee class
incomeObj.incomeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
//coffeeObj.coffeeSize = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)];
incomeObj.isDirty = NO;
[appDelegate.incomeArray addObject:incomeObj];
[incomeObj release];
NSLog(#"INCOME OBJECTS %#", incomeObj.incomeName);
//NSLog(#"CALLED");
}
}
}
else{
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory
NSLog(#"INCOME CALLED 5");
}
NSLog(#"INCOME CALLED 6");
}
I am calling the code in viewWillAppear as follows:
[Income getInitialDataToDisplay:[appDelegate getDBPath]];
Also this is the output from my console when the error occurs:
2011-06-17 12:21:48.307 CashCal[318:707] GET DB PATH CALLED
2011-06-17 12:21:48.310 CashCal[318:707] /var/mobile/Applications/2BD7CA1D-C7AB-4425-B5C1-974C4F4D057C/Documents/SQL.sqlite
2011-06-17 12:21:48.312 CashCal[318:707] INCOME CALLED 1
2011-06-17 12:21:48.314 CashCal[318:707] INCOME CALLED 5
2011-06-17 12:21:48.318 CashCal[318:707] INCOME CALLED 6
It appears the problem is with the first if statement opening the database. I really need help on this one
You should always destroy prepared statements by calling sqlite3_finalize(your_stmt). And you should always close youre connection not only if it sqlite3_open() failed.
Also do something like this:
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
//your code here
} else {
//print error
NSLog(#"sql-error: %s", sqlite3_errmsg(database));
}
for clarification, here a interface for your db, that should avoid opening the db when its allready open, and makes code cleaner
DBi.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface DBi : NSObject {
sqlite3* db;
}
- (void)opendDB;
- (void)closeDB;
- (NSArray*)getIcons;
#end
DBi.m
#import "DBi.h"
#import "Income.h"
static DBi *sharedDBi = nil;
#implementation DBi
- (void)dealloc {
sqlite3_close(db);
[super dealloc];
}
+ (DBi*)sharedManager {
if (sharedDBi == nil) {
sharedDBi = [[super allocWithZone:NULL] init];
[sharedDBi opendDB];
}
return sharedDBi;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
- (void)opendDB {
NSString *dbPath = [[NSBundle mainBundle]pathForResource:#"path_to_db_file"ofType:#"sqlite"];
//open the database
if(!sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK) {
NSLog(#"connection to db failed");
sqlite3_close(db);
}
}
- (void)closeDB {
sqlite3_close(db);
}
- (NSArray*)getIncoms {
NSMutableArray rArray = [[[NSMutableArray alloc] init] autorelease];
const char *sql = "select IncomeID, IncomeName from Income ORDER BY IncomeName asc";
//const char *sql2 = "select categoryID, Size from coffee";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(db, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Income *incomeObj = [[Income alloc] initWithPrimaryKey:primaryKey];
incomeObj.incomeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
incomeObj.isDirty = NO;
[rArray addObject:incomeObj];
[incomeObj release];
}
} else {
NSLog(#"sql-error in getIncoms: %s", sqlite3_errmsg(db));
}
sqlite3_finalize(selectstmt);
return rArray;
}
Now you could do something like that.
DBi *dbi = [[DBi alloc] init];
NSArray *incoms = [dbi getIncoms];
[dbi release];
hope, that should help
use this code
sqlite3 *database;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
////your Code
if(sqlite3_prepare_v2(database, [sqlStatement cStringUsingEncoding:NSUTF8StringEncoding], -1, &compiledStatement, NULL) == SQLITE_OK)
{
NSLog(#"%#",sqlStatement);
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
//your code
}
}
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
}
Use FMDB for you sqlite tasks. It's a bad practice to use sqlite calls everywhere in the application. Just search on google for FMDB Example you will find one. FMDB is much easier to implement then SQLIte because FMDB handles all the things.
It turns out I was calling the same SQL method in two different places in very quick succession before the statements had a chance to be finalised each time. I guess this caused some sort of overlap eventually leading to the statements becoming invalid. Thanks for all the help. I will definitely be using CoreData or FMDB next time.

Open two tables from one SQLite db in one iPhone Class?

small clarification is this possible to open two tables from one sqlite db in one iphone class??? but i can't open it please give me the solution i'm a beginner
here i tried coding
- (void)viewDidLoad {
[super viewDidLoad];
list = [[NSMutableArray alloc] init];
if ([material isEqualToString:#"Derlin"]) {
[self sel1];
}
else if([material isEqualToString:#"Helers"]){
[self sel2];
}
}
-(void)sel1 {
[self createEditableCopyOfDatabaseIfNeeded];
NSLog(#"numberOfRowsInSection");
sqlite3_stmt *statement = nil; // create a statement
const char *sql = "Select * from material"; //create a query to display in the tableView
if(sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sqlite3_open");
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0,#"Error Preparing Statement",sqlite3_errcode(database));
else
{
while(sqlite3_step(statement) == SQLITE_ROW) // if the connection exists return the row of the query table
{
achemical = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,0)];
arates = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,1)];
anotes = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,2)];
Chemical * chemic = [[Chemical alloc] initWithName:achemical rates:arates notes:anotes];
[list addObject:chemic];
[chemic release];
}
}
}
sqlite3_finalize(statement);
}
-(void)sel2 {
[self createEditableCopyOfDatabaseIfNeeded];
NSLog(#"numberOfRowsInSection");
sqlite3_stmt *statement = nil; // create a statement
const char *sql = "Select * from material1"; //create a query to display in the tableView
if(sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sqlite3_open");
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0,#"Error Preparing Statement",sqlite3_errcode(database));
else
{
while(sqlite3_step(statement) == SQLITE_ROW) // if the connection exists return the row of the query table
{
achemical = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,0)];
arates = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,1)];
anotes = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,2)];
Chemical * chemic = [[Chemical alloc] initWithName:achemical rates:arates notes:anotes];
[list addObject:chemic];
[chemic release];
}
}
}
sqlite3_finalize(statement);
}
thanks in advance
Sure, it's easy. Download FMDB, add it to your project, and add two FMResultSet objects in your class, one for each (query against each) table.

How to handle returned null from SQLite

I am using this in a method:
+ (void) getA:(NSString *)dbPath {
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "select a from a_table";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];
coffeeObj.aString = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,0)];
coffeeObj.isDirty = NO;
[appDelegate.aArray addObject:coffeeObj.aString];
[coffeeObj release];
}
}
}
else
sqlite3_close(database);
}
When db has a row, it works fine, but when it has no rows, it just crashes.
What i need to know is, how can I handle my code so that it should work properly when there is no row in DB.
What should I add/modify in my code to behave properly, when there is no rows in the db?
Regards
I know this is a very old question but just had this problem of myself and put a very easy method to solve this. Hope this might help other visitors
In Your code
Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];
coffeeObj.aString = [self checkNullForSQLStatmentColoumn:sqlite3_column_text(selectstmt, 0)];
-(NSString *) checkNullForSQLStatmentColoumn : (const unsigned char *) coloumn{
if(coloumn)
{
return [NSString stringWithUTF8String:(const char *)coloumn];
}
return #"";
}
Try this: to check if something is not NSNull type
if((NSNull *)YourResource != [NSNull null])