confused in sqlite select statement - iphone

I am trying get the data from my database but i am not getting solve out
I try like this
-(void)information
{
//[self createEditableCopyOfDatabaseIfNeeded];
NSString *filePath = [self getWritableDBPath];
sqlite3 *database;
if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK)
{
NSString *qu = #"Select Name FROM empl where SyncStatus ='1'";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [qu UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
char *firstColumn = (char *)sqlite3_column_text(compiledStatement, 0);
if (firstColumn==nil)
{
NSString *name= [[NSString stringWithUTF8String:firstColumn]autorelease];
NSLog(#"%c",name);
}
if(sqlite3_step(compiledStatement) != SQLITE_ROW )
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"UIAlertView" message:#"User is not valid" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
alert = nil;
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
it get crash And
It show me error that reason: '* +[NSString stringWithUTF8String:]: NULL cString'
* Call stack at first throw:

use like this
if(sqlite3_step(compiledStatement) == SQLITE_ROW )
{
char *firstColumn = (char *)sqlite3_column_text(compiledStatement, 0);
NSString *name= [[NSString alloc]initWithUTF8String:firstColumn];
}
I hope it will help you try this

I think firstColumn is NULL , it make program crash . You try to check data in database is null.

This is actually obvious because you are trying to fetch data which is NULL
Try for this code for checking NULL in your code:
if (sqlite3_column_text(compiledStatement, 0)!= nil)
i.e.
if (sqlite3_column_text(compiledStatement, 0)!= nil)
char *firstColumn = (char *)sqlite3_column_text(compiledStatement, 0);
else
char *firstColumn = #"";
NSString *name= [[NSString stringWithUTF8String:firstColumn]autorelease];
NSLog(#"%c",name);
try this...
Hope it helps....

I think there are 2 issues with this piece of code.
As already pointed out you are checking for equal to nil and not for
different from nil.
To order of the sql functions should be:
sqlite3_open
sqlite3_prepare_v2
sqlite3_step
sqlite3_column_text
You can also read about this order of statements at:
http://www.iosdevelopment.be/sqlite-tutorial/

Related

how to save the data in sqlite3 in iphone

i am trying to create the database using sqlite manager.But the values are not stored in database.If i click the save button the Alert Message will be displayed on like this "Data Insertion Failed".i am trying to rectify these problem.In this case i visit so many tutorials.But i cant rectify my problem.Yesterday onwards i am totally blocked to this issue.please give me any idea or suggestion how to save the data.Thanks for all to visit the question.T.C.
DataBase.m
// creation of DATABASE
-(BOOL)createDB
{
NSString *docsDir;
NSArray *dirPaths;
// Get the document directory
dirPaths=NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
docsDir=dirPaths[0];
// Build the path to the database file
databasePath=[[NSString alloc]initWithString:[docsDir stringByAppendingPathComponent:#"Feedback.db"]];
BOOL isSuccess=YES;
NSFileManager *fileManager=[NSFileManager defaultManager];
if([fileManager fileExistsAtPath:databasePath]==0)
{
const char *dbpath=[databasePath UTF8String];
if(sqlite3_open(dbpath, &database)==SQLITE_OK)
{
char *errMsg;
const char *sql_stmt= "create table if not exists Feeback details (Traineeid integer, Trainername text,Traineename text,Rating float)";
if(sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)!=SQLITE_OK)
{
isSuccess=NO;
NSLog(#"Failed to create table");
}
sqlite3_close(database);
return isSuccess;
}
else
{
isSuccess=NO;
NSLog(#"Failed to open/Create database");
}
}
return isSuccess;
}
// save data in the Database
-(BOOL) saveData:(NSString *)Traineeid Trainername:(NSString *)Trainername Traineename:(NSString *)Traineename Rating:(NSString *)Rating;
{
const char *dbpath=[databasePath UTF8String];
if(sqlite3_open(dbpath, &database)==SQLITE_OK)
{
NSString *insertSQL=[NSString stringWithFormat:#"insert into Feedbackdetails(Traineeid,Trainername,Traineename,Rating) values(\"%d\",\"%#\", \"%#\", \"%#\")",[Traineeid integerValue],Trainername,Traineename,Rating];
const char *insert_stmt=[insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL);
if(sqlite3_step(statement)==SQLITE_DONE)
{
return YES;
}
else
{
return NO;
}
sqlite3_reset(statement);
}
return NO;
}
FeebBackForm.m
-(IBAction)saveData:(id)sender
{
BOOL success=NO;
NSString *alertString = #"Data Insertion failed";
if (Traineeid.text.length>0 &&Trainername.text.length>0 &&Traineename.text.length>0 &&Rating.text.length>0)
{
success=[[DBManager getSharedInstance]saveData:Traineeid.text Trainername:Trainername.text Traineename:Traineename.text Rating:Rating.text];
}
else
{
alertString = #"Enter all fields";
}
if (success == NO)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertString message:nil
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
Your putting string quotes around your int params in your sql statement.
This may not be your only issue but you should bind params. It looks like you're putting quotes around integer values in the sql insert statement which are defined as integers in your table.
"create table if not exists Feeback details (Traineeid integer, Trainername text,Traineename text,Rating float)"
"insert into Feedbackdetails(Traineeid,Trainername,Traineename,Rating) values(\"%d\",\"%#\", \"%#\", \"%#\")"
Notice your double quotes around ints.
Also, log out the path to your database (even if running in simulator). Go to the sqlite cmd line and ensure the db exists and the empty table is there. This helps in troubleshooting.
Finally, take a look # the fmdb sqlite wrapper - it helps using sqlite but it's code also shows good patterns for using sqlite raw if that's your preference.
Here's a similar function from one of my samples which shows how to bind params. You should also finalize what you prepare:
- (void)updateContact: (Contact*)contact error:(NSError**)error
{
if (![self ensureDatabaseOpen:error])
{
return;
}
NSLog(#">> ContactManager::updateContact");
// prep statement
sqlite3_stmt *statement;
NSString *querySQL = #"update contacts set name=?,address=?,phone=? where id=?";
NSLog(#"query: %#", querySQL);
const char *query_stmt = [querySQL UTF8String];
// preparing a query compiles the query so it can be re-used.
sqlite3_prepare_v2(_contactDb, query_stmt, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [[contact name] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[contact address] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[contact phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int64(statement, 4, [[contact id] longLongValue]);
NSLog(#"bind name: %#", [contact name]);
NSLog(#"bind address: %#", [contact address]);
NSLog(#"bind phone: %#", [contact phone]);
NSLog(#"bind int64: %qi", [[contact id] longLongValue]);
// process result
if (sqlite3_step(statement) != SQLITE_DONE)
{
NSLog(#"error: %#", sqlite3_errmsg(_contactDb));
}
sqlite3_finalize(statement);
}

Getting error while executing SQLite command from application

I have this simple function in my application :
-(NSMutableArray *)SelectProductID:(NSMutableArray *)arr
{
NSLog(#"----------------");
sqlite3_stmt *statement;
NSMutableArray *arrPordID = [[NSMutableArray alloc]init];
#try
{
//Get productID
for(NSString *strSubProductID in arr)
{
NSString *s = [NSString stringWithFormat:#"SELECT ProductID FROM SubProducttable where SubProductID=%#",strSubProductID];
const char *sql = [s cStringUsingEncoding:NSASCIIStringEncoding];
if (sqlite3_prepare_v2(database, [s cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW){
char *dbString;
dbString = (char *)sqlite3_column_text(statement, 0);
NSString *pID = (dbString) ? [NSString stringWithUTF8String:dbString] : #"";
[arrPordID addObject:pID];
}
}
}
}
#catch (NSException *exception) {
#throw exception;
}
#finally {
sqlite3_finalize(statement);
}
return arrPordID;
}
I am encountering a strange problem here. When application reaches while (sqlite3_step(statement) == SQLITE_ROW){, loop is never entered. I don't know why. I executed the same query in SQLite manager (when application is not running). And I get result as a single one. The result I get is 2. But here I am getting nothing.
And yes, I always close the database in SQLite manager whenever I run my application. I have also cleaned the application, restarted XCode, and removed the application from simulator. But no success.
Also I saw a strange thing during debugging. While debugging, sqlite3_stmt *statement is always skipped. Is this the reason I am not getting any result?
Have you tried subproductId in single quotes?
NSString *s = [NSString stringWithFormat:#"SELECT ProductID FROM SubProducttable where SubProductID='%#'",strSubProductID];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlQuery = #"SELECT ProductID FROM SubProducttable where SubProductID=%#",strSubProductID;
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, statement, -1, &sqlQuery, NULL) == SQLITE_OK) {
while(sqlite3_step(sqlQuery ) == SQLITE_ROW) {
// Read the data and add to your array object
}
}
// Release the compiled statement from memory
sqlite3_finalize(statement);
}
sqlite3_close(database)

iphone: strange leak

Can anybody help me out why this piece of code is leaking and how can we handle it?
sqlite3 *database;
if (pickerList) {
self.pickerList=nil;
[pickerList release];
}
self.pickerList=[[NSMutableArray alloc] init];
NSString *dbPath = [self applicationDocumentsDirectory];
dbPath=[dbPath stringByAppendingPathComponent:#"database"];
dbPath=[dbPath stringByAppendingPathComponent:#"OFFENDERSDB.sqlite"];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
if (isAlertForViolationPicker) {
const char *sqlStatement = "SELECT * FROM VIOLATIONS_TBL";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *recSTR=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
[self.pickerList addObject:recSTR];
[recSTR release];
recSTR=nil;
}
}
//[tempRowArray release];
sqlite3_finalize(compiledStatement);
//sqlite3_reset(compiledStatement);
sqlite3_close(database);
}
else {
const char *sqlStatement = "SELECT * FROM PLAN_TBL";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *recSTR=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
[self.pickerList addObject:recSTR];
[recSTR release];
recSTR=nil;
}
}
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
}
sqlite3_reset(compiledStatement);
recSTR is leaking in this case and I have tried all the below mentioned solutions but none worked (updated the code)
Thanx in advance
It looks as though you may be leaking pickerList. You have a pointer to pickerList which you then set to nil. Then you send a release message to this point (which is in effect a no-op). If you use:
if (pickerList)
{
[pickerList release];
self.pickerList=nil;
}
instead of your current code, do you fare any better? Without seeing more code it's hard to say, but you definitely want to release before you set the ivar to nil. (This said if you you've done #property (retain) UIPickerList *pickerList then self.pickerList = nil will release pickerList. If you've done this then your [pickerList release] call is redundant.)
You may well get a report of a recSTR leaking from instruments. But that doesn't mean that the issue isn't with pickerList. Looking at the code, it would not unlikely that recSTR is owned by an instance of pickerList that is hanging around because you've discarded the pointer to it and then sent a release message to nil. So you'll end up with a leak of recSTR and pickerList.

how can I insert value into my sqlite3 database table?

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
}

Accessing an SQLite DB for two separate queries on iPhone App Initialization

I was successfully accessing my database to get a list of cities on the App launch. I tried running a second query against it right afterward to get the list of States but all that happens is that my app blows up with no usable error in the console (simply says "Program received signal: EXEC_BAD_ACCESS" and nothing more).
Here is the code, I was hoping someone could potentially explain to me what I'm doing wrong:
-(void) initializeDatabase{
// The database is stored in the application bundle
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"mydatabase.sqlite"];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK){
[self initializeCities:database];
[self initializeStates:database];
} else {
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
// Additional error handling, as appropriate...
}
}
-(void) initializeCities:(sqlite3 *)db {
NSMutableArray *cityArray = [[NSMutableArray alloc] init];
self.cities = cityArray;
[cityArray release];
// Get the primary key for all cities.
const char *sql = "SELECT id FROM my_table ORDER BY state";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW){
int primaryKey = sqlite3_column_int(statement, 0);
City *city = [[City alloc] initWithPrimaryKey:primaryKey database:db];
[cities addObject:city];
[city release];
}
}
// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}
-(void) initializeStates:(sqlite3 *)db {
NSMutableArray *statesArray = [[NSMutableArray alloc] init];
self.states = statesArray;
[statesArray release];
// Get the primary key for all cities.
const char *sql = "SELECT DISTINCT state FROM my_table ORDER BY state";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
// We "step" through the results - once for each row
while (sqlite3_step(statement) == SQLITE_ROW){
NSString *state;
state = (NSString *)sqlite3_column_text(statement, 0);
[states addObject:state];
[state release];
}
}
// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}
I can't debug this code as the debugger never hits my breakpoints at all.
If I remove the initializeStates method the app works as expected (albiet without a list of states).
You are releasing "state" without having allocated it. Try something like this:
while (sqlite3_step(statement) == SQLITE_ROW){
NSString *state = [[NSString alloc] initWithCString:(char*)sqlite3_column_text(statement, 0) encoding:NSASCIIStringEncoding];
//state = (NSString *)sqlite3_column_text(statement, 0);
[states addObject:state];
[state release];
}
Update: add cast above to fix compiler warning
Your problem is this:
NSString *state = (NSString *)sqlite3_column_text(statement, 0);
According to the documentation, sqlite3_column_text() returns a char*, not an NSString*.
Edit: You wouldn't have had this problem if you'd have used a wrapper ;)