Below is the code i am using:
FMDatabaseQueue *queue = [[DataBaseHelper sharedManager] queue];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *results = [db executeQuery:#"select * from EVENT where ESTATUS='unread' and HIT_ATTEMPTS < 5 "];
if([results next])
{
[results close];
#try {
BOOL success=FALSE;
NSString *query=[NSString stringWithFormat:#"insert into EVENT (EDATA, ESTATUS ,EUSER) values('%#','%#','%#')",#"google.com",#"unread",#"xyz"];
success = [db executeUpdate:query];
NSLog(#"create edata row, %d:%#", [db lastErrorCode], [db lastErrorMessage]);
}
#catch (NSException *exception) {
NSLog(#"Exception");
}
In the above code
success = [db executeUpdate:query]; is not working. I have tried placing breakpoints. After this line of code all exits. None of the logs get printed.
I am not sure why you are using a try and Catch, anywayz follow the steps it will surely work
Creating A Database
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"database.sqlite"];
FMDatabase *database = [FMDatabase databaseWithPath:path];
Opening The Database And Creating Tables(optional)
[database open];
//optional
[database executeUpdate:#"create table user(name text primary key, age int)"];
Querying The Database
FMResultSet *results = [database executeQuery:#"select * from user"];
while([results next]) {
NSString *name = [results stringForColumn:#"name"];
NSInteger age = [results intForColumn:#"age"];
NSLog(#"User: %# - %d",name, age);
}
[database close];
Related
I've made an app in which im using an sqlite database with fmdb wrapper for inserting and consulting data, the data is displayed into a table view, the problem is that when i run the app on an iphone 4 everything works well, but when i do it on an iphone 4s it doesn't..could someone please help me fix this issue.
Here are parts of my code:
Loading DB:
aPools = [[NSMutableArray alloc] init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"poolsDB" ofType:#"sqlite"];
mainDB = [[FMDatabase alloc] initWithPath:path];
[mainDB open];
FMResultSet *fResult = [ mainDB executeQuery:#"SELECT * FROM poolsData"];
while ([fResult next]) {
poolsData = [fResult stringForColumn:#"Name"];
[aPools addObject:poolsData];
}
[mainDB close];
Saving :
-(void) saveIntoDB:(NSString *)name withVolume:(float)volume type:(NSString *)type andDesc:(NSString *)desc {
[mainDB open];
[mainDB executeUpdate:#"INSERT INTO poolsData (Name,Volume,Type,Desc) values (?,?,?,?)",name,
[NSNumber numberWithFloat: volume] ,type,desc, nil];
[mainDB close];
}
Could it be that the table view works in diferent ways beetwen devices?
Try the following code:
for LOADING:
aPools = [[NSMutableArray alloc] init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"poolsDB" ofType:#"sqlite"];
FMDatabase* mainDB = [FMDatabase databaseWithPath:path];
if(![mainDB open])
{
return NO; //since the error in opening database
}
FMResultSet *fResult = [ mainDB executeQuery:#"SELECT * FROM poolsData"];
while ([fResult next]) {
poolsData = [fResult stringForColumn:#"Name"];
[aPools addObject:poolsData];
}
[mainDB close];
code for SAVING:
-(void) saveIntoDB:(NSString *)name withVolume:(float)volume type:(NSString *)type
andDesc:(NSString *)desc {
FMDatabase* mainDB = [FMDatabase databaseWithPath:path];
if(![mainDB open])
{
return; //since the error in opening database
}
[mainDB beginTransaction];
[mainDB executeUpdate:#"INSERT INTO poolsData (Name,Volume,Type,Desc) VALUES
(?,?,?,?)",name,
[NSNumber numberWithFloat: volume] ,type,desc];
[mainDB commit];
[mainDB close];
}
Below is my code, i am trying to fetch data from my.sqlite database but it is not executing my if case. It always enters in else condition. What wrong thing i am doing?
I am not able to execute my if case i.e. if(sqlite3_prepare_v2(database, sqlQuerry, -1, &querryStatement, NULL)==SQLITE_OK)
sqlite3 *database;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"my.sqlite"];
const char* dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &database)==SQLITE_OK)
{
const char *sqlQuerry="SELECT * FROM Contacts;";
sqlite3_stmt *querryStatement;
if(sqlite3_prepare_v2(database, sqlQuerry, -1, &querryStatement, NULL)==SQLITE_OK)
{
NSLog(#"conversion successful....");
while (sqlite3_step(querryStatement)==SQLITE_ROW)
{
NSString *addressField = [[NSString alloc] initWithUTF8String:
(const char *)
sqlite3_column_text(querryStatement, 0)];
NSString *phoneField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(querryStatement, 1)];
NSLog(#"DB ID :- %#",addressField);
NSLog(#"DB NAME :- %#",phoneField);
}
sqlite3_reset(querryStatement);
}
else {
NSLog(#"error while conversion....");
}
sqlite3_close(database);
}
/////////////////////////////////////////////////////////////////////////////////
I tried using FMDB and did it as bellow:
But my *s and *results object are getting nil value and while statement is not executed
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"my.sqlite"];
FMDatabase* database = [FMDatabase databaseWithPath:path];
[database open];
FMResultSet *s = [database executeQuery:#"SELECT COUNT(*) FROM Contacts"];
while ([s next])
{
int totalCount = [s intForColumnIndex:0];
NSLog(#"Count : %i", totalCount);
}
FMResultSet *results = [database executeQuery:#"select * from Contacts"];
while([results next])
{
NSString *contact_id = [results stringForColumn:#"contact_id"];
NSString *name = [results stringForColumn:#"name"]; //
NSLog(#"User: %# - %#",name, contact_id);
}
[database close];
Replace your first six lines by the following code:
sqlite3 *database;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"my.sqlite"];
NSLog(#"DATABASE PATH=%#",databasePath);
NSFileManager *fn=[NSFileManager defaultManager];
NSError *error;
BOOL success=[fn fileExistsAtPath:databasePath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"my.sqlite"];
success = [fn copyItemAtPath:defaultDBPath toPath:databasePath error:&error];
}
const char *dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &database)==SQLITE_OK)
{
//. . . . your code...//
}
If you have a problem with any sqlite API then you need to report the error using sqlite3_errmsg() (reference) and this will help you track down your problem.
Change your code to report the error and update your question with the log output:
if (sqlite3_open(dbPath, &database) == SQLITE_OK)
{
...
}
else
{
NSLog("Failed to open database '%#': %s", databasePath, sqlite3_error(database));
}
According to the documentation for sqlite3_open() (here):
.... Otherwise an error code is returned. The sqlite3_errmsg() or
sqlite3_errmsg16() routines can be used to obtain an English language
description of the error following a failure of any of the
sqlite3_open() routines.
I found where I was going wrong. I created & inserted data to my database using Core Data. At the time of fetching I wanted to fire very complex queries, so I had to switch to SQLite. I was doing everything fine but getting error: Table not found.
The actual problem was that CoreData changed every table name of my database with a name prepending a "z", so my table name Contacts changed to ZContacts and column names in similar manner. When I opened my sqlite database in SQLite Manager I found where I was wrong.
I could read from my SQLITE DB, but unable to update it. I wonder if the database is writable.
When i copy the SQL to the SQL console the code gets executed successfully. So there's no problem with the SQL.
-(BOOL) updateScores{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"uniques.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
BOOL success;
if ([db open]) {
if ([db hadError]) {
NSLog(#"DB Error %d: %#", [db lastErrorCode], [db lastErrorMessage]);
}
success = [db executeUpdate:[NSString stringWithFormat:#"UPDATE Score SET answer='11' WHERE name LIKE 'jack'"]];
if (success) {
NSLog(#"OK");
}else {
NSLog(#"FAIL");
}
[db close];
}else {
NSLog(#"Problem with DB");
}
return success;
}
Always pass the arguments to SQL query as an object type, please look at the way arguments are passed to the SQL query. Even if you are passing a number, pass it as
[NSNumber numberWithInt:someValue]
Try this:
-(BOOL) updateScores
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"uniques.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
BOOL success = NO;
if ([db open] != YES) {
NSLog(#"DB Error %d: %#", [db lastErrorCode], [db lastErrorMessage]);
return NO; //VERY IMPORTANT
}
[db beginTransaction];
success = [db executeUpdate:#"UPDATE scores SET answer = ? WHERE name like ?", #"1", #"jack"];
if (success) {
NSLog(#"OK");
[db commit];
[db close];
}else {
NSLog(#"FAIL");
}
return success;
}
Friend it just general question .
How can write and retrieve the data on to the file .And how can make this file in .csv format.
For example i am retrieve data like that
NSString *coords = [[[NSString alloc] initWithFormat:#"%f,%f\n",longitude,latitude] autorelease];
[locations addObject:coords];
Than how can write this data on to the file in .csv format.
And than How can i retrieve this data
To write csv
NSString *coords = [[[NSString alloc] initWithFormat:#"%f,%f\n",longitude,latitude] autorelease];
NSData *csvData = [coords dataUsingEncoding:NSUTF8StringEncoding];
NSArray *UsrDocPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DocsDir = [UsrDocPath objectAtIndex:0];
NSString *csvPath = [DocsDir stringByAppendingPathComponent:#"coords.csv"];
//This is upto your logic that do you want to remove existant csv file or not
BOOL success = [FileManager fileExistsAtPath:csvPath];
if(success){
[FileManager removeItemAtPath:csvPath error:&error];
}
[csvData writeToFile:csvPath atomically:YES];
To read from file
NSData *csvData = [NSData dataWithContentsOfFile:csvPath];
NSString *strCSV = [[NSString alloc]initWithData:csvData encoding:NSUTF8StringEncoding];
Hope it helps
There is a csv parser written by dave delong. you can use that.
First, you'll want to make sure that you're using FMDB to access the database, because people who use the SQLite C API directly in Objective-C are masochists. You can do that like this:
FMDatabase *db = [[FMDatabase alloc] initWithPath:#"/path/to/db/file"];
FMResultSet *results = [db executeQuery:#"SELECT * FROM tableName"];
while([results nextRow]) {
NSDictionary *resultRow = [results resultDict];
NSArray *orderedKeys = [[resultRow allKeys] sortedArrayUsingSelector:#selector(compare:)];
//iterate over the dictionary
}
As for writing to a CSV file, well there's code for that too:
#import "CHCSV.h"
CHCSVWriter * csvWriter = [[CHCSVWriter alloc] initWithCSVFile:#"/path/to/csv/file" atomic:NO];
//write stuff
[csvWriter closeFile];
[csvWriter release];
And to combine them, you'd do:
FMDatabase *db = [[FMDatabase alloc] initWithPath:#"/path/to/db/file"];
if (![db open]) {
//couldn't open the database
[db release];
return nil;
}
FMResultSet *results = [db executeQuery:#"SELECT * FROM tableName"];
CHCSVWriter *csvWriter = [[CHCSVWriter alloc] initWithCSVFile:#"/path/to/csv/file" atomic:NO];
while([results nextRow]) {
NSDictionary *resultRow = [results resultDict];
NSArray *orderedKeys = [[resultRow allKeys] sortedArrayUsingSelector:#selector(compare:)];
//iterate over the dictionary
for (NSString *columnName in orderedKeys) {
id value = [resultRow objectForKey:columnName];
[csvWriter writeField:value];
}
[csvWriter writeLine];
}
[csvWriter closeFile];
[csvWriter release];
[db close];
[db release];
That will write the contents of the tableName table out to a CSV file.
Then you can use CSV Parser to parse the CSV and get data.
In my app, I want to export a SQLite database file to CSV file..
Could you suggest me how to do this?
Thanks.
First, you'll want to make sure that you're using FMDB to access the database, because people who use the SQLite C API directly in Objective-C are masochists. You can do that like this:
FMDatabase *db = [[FMDatabase alloc] initWithPath:#"/path/to/db/file"];
FMResultSet *results = [db executeQuery:#"SELECT * FROM tableName"];
while([results nextRow]) {
NSDictionary *resultRow = [results resultDict];
NSArray *orderedKeys = [[resultRow allKeys] sortedArrayUsingSelector:#selector(compare:)];
//iterate over the dictionary
}
As for writing to a CSV file, well there's code for that too:
#import "CHCSV.h"
CHCSVWriter * csvWriter = [[CHCSVWriter alloc] initWithCSVFile:#"/path/to/csv/file" atomic:NO];
//write stuff
[csvWriter closeFile];
[csvWriter release];
And to combine them, you'd do:
FMDatabase *db = [[FMDatabase alloc] initWithPath:#"/path/to/db/file"];
if (![db open]) {
//couldn't open the database
[db release];
return nil;
}
FMResultSet *results = [db executeQuery:#"SELECT * FROM tableName"];
CHCSVWriter *csvWriter = [[CHCSVWriter alloc] initWithCSVFile:#"/path/to/csv/file" atomic:NO];
while([results nextRow]) {
NSDictionary *resultRow = [results resultDict];
NSArray *orderedKeys = [[resultRow allKeys] sortedArrayUsingSelector:#selector(compare:)];
//iterate over the dictionary
for (NSString *columnName in orderedKeys) {
id value = [resultRow objectForKey:columnName];
[csvWriter writeField:value];
}
[csvWriter writeLine];
}
[csvWriter closeFile];
[csvWriter release];
[db close];
[db release];
That will write the contents of the tableName table out to a CSV file.
Simply do a SELECT on each table and print out the value of each column as required to a text file.