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.
Related
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.
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.
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)....
I am writing a simple query as below
const char *sql = "insert into abc(name) values ('Royal')";
and this will insert each time 'Royal' into my 'name', so now I want to take input from user each time as names of hotel and wants to save them instead of 'Royal', so what should I do?
If you are not clear to my question, you may as me again,,,,,
this code is very simple for insert the value in sqlite3 table
-(void)writeValueInSettings:(NSMutableArray *)arrayvalue
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
database *objectDatabase=[[database alloc]init];
NSString *stringvalue2=[objectDatabase countValue];
[objectDatabase release];
NSLog(#"opened");
NSString *sql1;
sql1=[[NSString alloc] initWithFormat:#"insert into setting values('%i','%i','%i','%#','%i','%i','%#','%i','%i','%i','%i','%i','%i','%#');",intvalue1,
[[arrayvalue objectAtIndex:0] intValue],[[arrayvalue objectAtIndex:1] intValue],[arrayvalue objectAtIndex:2],[[arrayvalue objectAtIndex:3] intValue],[[arrayvalue objectAtIndex:4]intValue ],[arrayvalue objectAtIndex:5],[[arrayvalue objectAtIndex:6]intValue],[[arrayvalue objectAtIndex:7]intValue ],[[arrayvalue objectAtIndex:8] intValue],[[arrayvalue objectAtIndex:9] intValue],[[arrayvalue objectAtIndex:10]intValue ],[[arrayvalue objectAtIndex:11]intValue],[arrayvalue objectAtIndex:12]];
char *err1;
if (sqlite3_exec(myDatabase,[sql1 UTF8String],NULL,NULL,&err1)==SQLITE_OK)
{
NSLog(#"value inserted:");
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Attention" message:#"You inserted successfully" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
}
[sql1 release];
sqlite3_close(myDatabase);
}
}
you need to connect to a database
- (sqlite3 *)database {
if (nil == db) {
NSString *path = <path to your database>;
int res = sqlite3_open([path UTF8String], &db);
if (res != SQLITE_OK){
// handle the error.
db = nil;
return nil;
}
}
return db;
}
then you can call this with the query
-(void)executeQuery:(NSString *)query{
sqlite3_stmt *statement;
if (sqlite3_prepare_v2([self database], [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
sqlite3_step(statement);
}else{
// handle the error.
}
sqlite3_finalize(statement);
}
-(void)dealloc {
//close database connection
sqlite3_close(db);
db = nil;
[super dealloc];
}
-(NSArray *) executeSelect:(NSString *)query {
//Data search block****************************************
char *zErrMsg;
char **result;
int nrow, ncol;
sqlite3_get_table(
[self database], /* An open database */
[query UTF8String], /* SQL to be executed */
&result, /* Result written to a char *[] that this points to */
&nrow, /* Number of result rows written here */
&ncol, /* Number of result columns written here */
&zErrMsg /* Error msg written here */
);
NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:3];
for (int i=0; i<nrow; i++){
[returnArray addObject:[NSString stringWithUTF8String:result[ncol + i]]];
}
sqlite3_free_table(result);
return returnArray;
}
Hi
if Your getting user inputs in userinput textfield
NSString *qry=[NSString stringwithformat:#"insert into abc(name) values (\"%#\")",userinput.text];
const char *sql = [qry UTF8string];
sqlite3 *contactDB;
const char *dbpath = [databasePath UTF8String]; // Convert NSString to UTF-8
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) == SQLITE_OK)
{ // SQL statement execution succeeded
}
} else {
//Failed to open database
}
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])