How to add nsmutablearray into the sqlite database table?Can any one help me to code?
You can use :
for (int i = 0; i < [mutArray count]; i++)
{
NSString *string = [mutArray objectAtIndex:i];
// insert query
insert into table_name ('string') values(column_name);
}
Use looping Controls to sort the array and insert each values
Example:
for(int itemIndex = 0; itemIndex < [yourArray count];itemIndex++){
NSString *myname = [yourArray objectAtIndex:itemIndex];
//insert myname to database.
}
To retrieve, you can use the sample below code
if(sqlite3_open([path UTF8String], &dataBase) == SQLITE_OK)
{
NSString *query = [NSString stringWithFormat:#"select name from syncTable where Crc = %d",crc]; const char *sql = [query UTF8String];
sqlite3_stmt *statement;
if (sqlite3_prepare(dataBase, sql, -1, &statement, NULL) == SQLITE_OK)
{
char *name;
unsigned int value;
while(sqlite3_step(statement) == SQLITE_ROW)
{
name = (char *)sqlite3_column_text(statement, 0);
[yourArray addObject:[NSString stringWithUTF8String:name]];
}
sqlite3_finalize(statement);
}
}
Here is a list of tutorials for using sqlite with iphone. Its not a matter of simulator or device. It will work fine with simulator also.
Create your db structure properly and work based on this tutorials.
Or
I'd recommend you to use Core Data if you want you work with databases on iPhone OS.
This tutorial should match your app quite well.
Please ask if any more questions.
Related
I have a simple program that update a record of a table
The table is "person" with two columns "name" and "age";
some records have been inserted, as follows:
name age
tom 20
andy 30
han 25
Now I am writing a program to update a row in the table:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *text=#"andy";
NSString *query=[NSString stringWithFormat:#"UPDATE person SET age=%d WHERE name='%#'",30,text];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query UTF8String],-1,&statement,NULL);
sqlite3_finalize(statement);
sqlite3_close(contactDB);
The program works fine, but the database is not updated (I am using SQLite Manager to browser the database)
When I try reading from database, it works well:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *query1=[NSString stringWithFormat:#"SELECT * FROM person WHERE age=%d;",30];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query1 UTF8String],-1,&statement,NULL);
sqlite3_step(statement);
NSString *result=[[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
label.text=result;
sqlite3_finalize(statement);
sqlite3_close(contactDB);
-(void)updateSetting:(NSArray *)arr
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
sqlite3_stmt *compiledStmt;
NSString *sqlStmt=[NSString stringWithFormat:#"UPDATE setting SET flow='%#',formate='%#' WHERE primaryKey=%i;",[arr objectAtIndex:0],[arr objectAtIndex:1],1];
if(sqlite3_prepare_v2(myDatabase, [sqlStmt UTF8String],-1,&compiledStmt, NULL)==SQLITE_OK)
{
NSLog(#"Successful update");
}
sqlite3_step(compiledStmt);
sqlite3_close(myDatabase);
}
}
I already faced this issues. Whats the problem behind this is you passed the query as a string format so you have to use the ; at the end of the query statement.
NSString *query=[NSString stringWithFormat:#"UPDATE questionbank SET age=%d WHERE name='%#';",30,text];
Please make a checking like below before you perform your sqlite3_step method.
const char *sqlQuery = "UPDATE SETTINGS SET someFlag = 0";
sqlite3_stmt *insertStatement = nil;
int success = 0;
if(sqlite3_prepare_v2(sqliteDatabase, sqlQuery, -1, &insertStatement, NULL) == SQLITE_OK)
{
success = sqlite3_step(insertStatement);
if(insertStatement)
{
sqlite3_finalize(insertStatement);
}
if(success == SQLITE_ERROR)
{
return NO;
}
return YES;
}
return NO;
So that you can figure out, where the problem is.
You need to check whether you could access and open the database or not. Simply place your update segment in a if-statement like this: if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK).
Also try to add NSLog(#"%s", sqlite3_errmsg(database)); after your prepare to see if there was any errors.
The answer for this problem is that the database in the main bundle is read-only
I can not insert data into sqlite3 file on XCode
I'm trying to display food by type to a user. The different types of foods are different elements in a table (fruits, veggies, meats, etc). I have all the foods in one database using sqlite. How can I query this database using objective c so that I can display only the correct type of food the user selected in the next view's table?
We use FMDB in two apps. It works fine.
-(NSArray *)GetAllFoods
{
NSMutableArray *filesArray = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
NSString *DBPath = [ClsCommonFunctions GetDatabasePath];
if ([self OpenDBWithPath:DBPath])
{
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "your query";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(filesDB, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Need to get data from database...
NSSstring *foodObj = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)]
[filesArray addObject:foodObj];
FileObj = nil;
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
sqlite3_close(filesDB);
}
return filesArray;
I am facing one problem while using sqlite in iOS 5. I am fetching records from two tables: one in Recipe & other in Ingredients from one Menu.db
From Recipe table I get all record and one recipeid on that basis I fetch records from ingredients table. It takes no time to fetch record when run on iOS 4.2 but when I run on iOS 5 it takes time to fetch the records. See the following code:
NSString *query = [NSString stringWithFormat:#"select id from Recipes"];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
rcp.recipeID = sqlite3_column_int(selectstmt, 0);
NSString *sql = [NSString stringWithFormat:#"select Name from Ingredients where recipeId = %d",rcp.recipeID];
sqlite3_stmt *stmt2;
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt2, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt2) == SQLITE_ROW) {}
}
}
}
Why is this issue coming in iOS 5.0, the same code runs fine on iOS 4.0, 4.2?
I know, code I have written is right,I want to know the exact reason behind this Performance issue in iOS 5.0 for Sqlite bcoz my app is totally build around database.
Try with using two different functions
After you finish with complete execution of your first query, start with second query.
For example :-
NSString *query = [NSString stringWithFormat:#"select id from Recipes"];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
rcp.recipeID = sqlite3_column_int(selectstmt, 0);
}
}
and then call
NSString *sql = [NSString stringWithFormat:#"select Name from Ingredients where recipeId = %d",rcp.recipeID];
sqlite3_stmt *stmt2;
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt2, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt2) == SQLITE_ROW) {}
Hope this helps to solve your issue.
I think you linked against libsqlite3.dylib. You should link the libsqlite3.0.dylib library instead.
If you want contever your .db to .sqlite
open your .db file select the table File-> Export--> Table from CSV (save your file with .csv format)
(like this way you select all table)
then open .sqlite file
File-> Import--> Table from CSV
after your .csv file choose a dialog box appear
in that Extract field names from first line must tick marked
now your sqlite file is ready.
put this file into your project
then set your .sqlite/.db file path
now set your select query as like this
#import <sqlite3.h>
-(void)SelectSqlData:(NSString *)SearchString
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"yourfileName.sqlite"];
sqlite3_stmt *compiledStatement;
sqlite3 *database;
if(sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement;
sqlStatement = "select c.field1,c.field2,c.field3,c.field4 from YourTableName1 as c, YourTableName2 as b where b.Artist_Id = ?";
sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
//printf("\nError===%s",sqlite3_errmsg(database));
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_text(compiledStatement,1,[SearchString UTF8String] , -1,SQLITE_STATIC);
while(sqlite3_step(compiledStatement) == SQLITE_ROW )
{
NSString *str_field1=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *str_field2=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *str_field3=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *str_field4=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// add str_field into array
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
This probably isn't the answer you're looking for, but here's a small tip to improve performance.
NSString *query = [NSString stringWithFormat:#"select id from Recipes"];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
rcp.recipeID = sqlite3_column_int(selectstmt, 0);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//NSString *sql = [NSString stringWithFormat:#"select Name from Ingredients where recipeId = %d",rcp.recipeID];//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sqlite3_stmt *stmt2;
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt2, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt2) == SQLITE_ROW) {}
}
}
}
Every iteration of the while loop, you create a new NSString object (NSString *sql = ...), so maybe you should instead do this:
NSString *query = [NSString stringWithFormat:#"select id from Recipes"];
NSString *sql = [NSString stringWithFormat:#"select Name from Ingredients where recipeId = %d",rcp.recipeID];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
rcp.recipeID = sqlite3_column_int(selectstmt, 0);
sqlite3_stmt *stmt2;
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt2, NULL) == SQLITE_OK) {
while(sqlite3_step(stmt2) == SQLITE_ROW) {}
}
}
}
Hope this helps a bit!
The function GetListBySQL is optimized and iOS versions independent. May it will help you out.
-(NSMutableArray*)GetListBySQL:(NSString*)SQL
{
NSMutableArray* Array;
Array=[[NSMutableArray alloc]init];
NSStringEncoding enc = [NSString defaultCStringEncoding];
sqlite3_stmt *select_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &select_statement, NULL) != SQLITE_OK) {
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[NSString stringWithCString:sqlite3_errmsg(database) encoding:enc] ]];
NSAssert1(0, #"%#", errString);
}
int columncount=sqlite3_column_count(select_statement);
NSMutableDictionary* dic;
while (sqlite3_step(select_statement) == SQLITE_ROW)
{
dic=[[NSMutableDictionary alloc]init];
for(int j=0;j<columncount;j++)
{
if(sqlite3_column_text(select_statement, j)!=nil)
[dic setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(select_statement, j)] forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
else
[dic setObject:#"" forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
}
[Array addObject:dic];
[dic release];
}
sqlite3_finalize(select_statement);
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray: Array];
[Array release];
return arr;
}
Another alternative is to change SQLite to a Key/Value database like LevelDB (from google) or TokyoCabinet. I'm using LevelDB for two project right now and is working really good, and I used TokyoCabinet in the past also, the problem with TokyoCabinet is that is LGPL, so I'm not sure if is fully compatible with the iOS environment, but anyway I had several Apps in the appstore using Tokyo Cabinet (don't tell Apple).
For using both of them you will need a wrapper (Or maybe you can develop your own). This is a quick comparison and the available wrappers:
LevelDB: It seems to be one of the fastest out there (if not the fastest, take a look at their benchmarks). And as wrapper I'm currently using NULevelDB, if you have any problems adding it to your project let me know (I had some).
TokyoCabinet: It seems to be no so fast as LevelDB (I haven't run tests, I dropped it because of the license problems), but in the official page they recommend using their new library called KyotoCabinet that I haven't tested yet but is supposed to be faster. The wrapper I used was made by the amazing Aaron Hillegass, and it is called BNRPersistence.
As a recommendation, give a try to LevelDB, there is a bigger community behind, and the wrapper (NULevelDB) is simple and friendly.
Good luck!
I have a SQLite database that I am creating in my iOS application. A series of numbers are being stored in this database. I want to sum the entire column, and return the data to be displayed within the application.
Everything writing to the DB is working properly, but I am stuck trying to return the summed data. Any help would be greatly appreciated.
-(void) dataReturn: (NSString *) tableNamed{
NSString *myData = [NSString stringWithFormat:#"SELECT SUM(column1) AS data1 FROM myDB", tableNamed];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, [myData UTF8String], -1, &statement, nil) ==SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW){
int *field2 = (int *) sqlite3_column_int(statement, 1);
NSString *myString =[[NSString alloc] initWithFormat:#"%#", field2];
}
}
}
Hello Nathan making a call as
[self dataReturn:#"Bill"];
to function
-(void)dataReturn:(NSString *)tableName{
sqlite3 *database;
sqlite3_stmt *statement;
NSString *queryString = [NSString stringWithFormat:#"SELECT SUM(price) AS TOTAL FROM %#", tableName];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
if(sqlite3_prepare_v2(database, [queryString UTF8String], -1, &statement, nil) == SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW) {
int field1 = sqlite3_column_int(statement, 0);
NSLog(#"The sum is %d ", field1);
}
}
}
}
will Fetch you desired data. The schema for Table "Bill" is "CREATE TABLE Bill (price double,quantity INTEGER)". The result fetched will have columns indexed from "0" so we pass 0 for first column. Hope you can take some hint from it. Cheers!!
int field1 = sqlite3_column_int(statement, 0);
From the sqlite3_column_int docs:
The leftmost column of the result set has the index 0.
Additionally, that function returns an int, not an int*. Try:
int field2 = sqlite3_column_int(statement, 0);
I just started looking into SQLite for the iPhone SDK. I have been looking at this tutorial and I am wondering how can I find an ID and store the information in that field of the ID? (the tutorial increments an ID every time I press save).
Also, how can I loop though the whole database e.g., add all the id numbers up? Is there a command?
Not much changes in the database access in the methods. Only the SQLite query changes. It should be something on these lines.
- (NSInteger) sumOfIds
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
NSString *result;
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *querySQL = #"SELECT sum(id) FROM contacts";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *result = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
}
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
}
return [result floatValue];
}