Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I created database and also created table in that by using sqlite manager(mozilla).Now i want to retrieve that data into my iOS application.How can i do with programatically. Can you please any one help me how to do that. Thank you.
Use something like this:
import:
#import "sqlite3.h"
CHECK IF DB EXISTS:
NSString *docsDir;
NSArray *dirPaths;
NSString *databasePath;
sqlite3 *DB;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"YourDbName.sqlite"]]; //put your db name here
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &DB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS YourTable (Value INTEGER PRIMARY KEY, column TEXT)";
if (sqlite3_exec(DB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
}
sqlite3_close(DB);
}
}
Get DB Values:
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &DB) == SQLITE_OK) //News is a sqlite variable initialized like this: sqlite3* News;
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT * FROM YourDBName"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(DB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSString* example; //example variable to assign data from db
example = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]; //change the 0 to 1,2,3.... for every column of your db
}
sqlite3_finalize(statement);
}
sqlite3_close(DB);
}
To retrieve that data into your iOS application.follow following steps
lets consider your SQlite DB have name YourDB which have table information and columns Name, Place and City and DatabasePath is your path where you store your SQlite DB
const char *dbpath = [DatabasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &YourDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT Place, City FROM students WHERE Name=Bob"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(YourDB,query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *Place = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
NSString *City = [[NSString alloc]
initWithUTF8String:(const char *)
sqlite3_column_text(statement, 1)];
}
sqlite3_finalize(statement);
}
sqlite3_close(YourDB);
}
Put that "sqlite" file in App's bundle and then you can use that file.
Related
I checked from sqlitebrowser that I successfully created sqlite and inserted data to sqlite, but now my problem is I could not read data from sqlite. I am new to sqlite.
Should I open the sqlite first, and read it? Where is wrong on my code below?
This code for open the existing sqlite.
-(void)openSqlite{
NSString *docsDir = [NSString stringWithFormat:#"Questiondata.db"];
NSArray *dirPaths;
_databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"Questiondata.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:_databasePath] == NO) {
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) {
char *errorMessage;
const char *sql_statement ="CREATE TABLE IF NOT EXISTS users (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)";
if (sqlite3_exec(_contactDB,sql_statement,NULL,NULL,&errorMessage) != SQLITE_OK) {
NSLog(#"Failed to create the table");
}
sqlite3_close(_contactDB);
}
else{
NSLog(#"Fail to open/create the table");
}
}
}
This is code for read data from existing sqlite.
-(void)readData{
NSLog(#"we came here");
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB)) {
NSString *querySQL = [NSString stringWithFormat:#"SELECT * FROM Questions WHERE QuestionNumber = 1"];
const char*query_statement = [querySQL UTF8String];
if (sqlite3_prepare_v2(_contactDB, query_statement, -1, &statement, NULL)== SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_ROW) {
NSString *addressfield = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,0)];
NSLog(#"finddata:%#",addressfield);
}else{
NSLog(#"notfinddatabase");
}
sqlite3_finalize(statement);
}else{
NSLog(#"failed to serache database");
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
NSLog(#"not be here");
}
}
In openSqlite method
const char *sql_statement ="CREATE TABLE IF NOT EXISTS users (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)";
and in your query
NSString *querySQL = [NSString stringWithFormat:#"SELECT * FROM Questions WHERE QuestionNumber = 1"];
table name and column name are not same.
Change in Place "Questions" with "users" .
and also change "QuestionNumber" with the table column.
May be, it will helps you or feel free.
sqlite doesn't report all errors until you start accessing the data. For example just about any filename and path will pass without errors.
First of all you must check that, the database is in the Documents folder?
It's not there by default.
Perhaps it's in the main bundle?
Try this:
NSString *dbName = [[NSBundle mainBundle] pathForResource:#"dbFile" ofType:#"db"];
Using php for an example:
$conn = new mysqli('localhost', 'xxx', '123456', 'xxx');
Just define $conn once, I can pass $conn to all other methods, so that i don't need to repeat the connection again when I run another query, and it's a lot faster.
function example($conn) {
// do some db stuff here
}
Can I do the same thing in IOS sqlite3? Many thanks for helping.
- (void) syncScale {
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:#"ALDI.db"]];
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
NSString *postSetting ;
postSetting = [NSString stringWithFormat:#"scaleData={\"scaleDB\":["];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *querySQL = #"SELECT * From Table1";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
// do something here
}
sqlite3_finalize(statement);
} else {
NSLog(#"Steps Data not found");
}
sqlite3_close(contactDB);
}
}
What I usually do, is that keep the opening of database in separate block/function with a boolean return ,rather finalize and rest the sqlite statement; Since the opening of database is made of almost static contents, the function doesn't need any parameters
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I am using SQLite DB in my iOS app. In my screen 1, I was successfully able to create a Database, a table, insert into it and retrieve from it.
However from screen 2 when I am trying to create a table in the same database and insert values, I am unable to.
This is the code which I am using.
-(void) createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"coning.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS order (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT UNIQUE , ADDRESS TEXT UNIQUE, PHONE TEXT UNIQUE)";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table");
}
sqlite3_close(_contactDB);
} else {
NSLog(#"Failed to open/create database");
}
}
}
- (void)saveData {
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT OR REPLACE INTO order (name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
#"name", #"address", #"phone"];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"added");
} else {
NSLog(#"Failed to add contact");
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
I have been using the same code to add entries in table 1 but when I do the same to create table 2, its says 'Failed to add contact'. Can someone suggest where I might be going wrong?
Also I want to make the PK of table 1 as a FK in table 2.
You can use sqlite3_exec() method instead of sqlite3_step().
sqlite3_exec() will execute whatever the query you have given.
I am sure, It will definitely help you.
-(BOOL)createNewTableInExistingDb
{
NSArray *array=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath=[array objectAtIndex:0];
filePath =[filePath stringByAppendingPathComponent:#"database.db"];
NSFileManager *manager=[NSFileManager defaultManager];
BOOL success = NO;
if ([manager fileExistsAtPath:filePath])
{
success =YES;
}
if (!success)
{
NSString *path2=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.db"];
success =[manager copyItemAtPath:path2 toPath:filePath error:nil];
}
createStmt = nil;
NSString *tableName=#"SecondTable";
if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
if (createStmt == nil) {
NSString *query=[NSString stringWithFormat:#"create table %#(RegNo integer, name text)",tableName];
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &createStmt, NULL) != SQLITE_OK) {
return NO;
}
sqlite3_exec(database, [query UTF8String], NULL, NULL, NULL);
return YES;
}
}
return YES;
}
I have a table called Budgets that stores its settings, values, and a purchases nsarray full of the object purchases.
I am not sure what I am doing wrong in my method right here, but it will not update the database on an existing entry. It saves a new budget just fine.
- (BOOL) saveBudget:(Budget *)budget
{
BOOL success = false;
sqlite3_stmt *statement = NULL;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
if (budget.budgetID > 0) {
NSLog(#"Existing data, Update Please");
NSString *updateSQL = [NSString stringWithFormat:#"UPDATE BUDGETS set name = '%#', budget = '%#', customdate = '%d', customday = '%d', rolloverp = '%d', rollovern = '%d', purchases = ?8 WHERE id = ?", budget.name, budget.budget, budget.customDate, budget.customDay, budget.rolloverP, budget.rolloverN];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL);
sqlite3_bind_int(statement, 1, budget.budgetID);
sqlite3_bind_blob(statement, 8, [budget.purchases bytes], [budget.purchases length], SQLITE_TRANSIENT);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
else
{
NSLog(#"New data, Insert Please");
NSString *insertSQL = [NSString stringWithFormat:#"INSERT INTO BUDGETS (name, budget, customdate, customday, rolloverp, rollovern, purchases) VALUES (\"%#\", \"%#\", \"%d\", \"%d\", \"%d\", \"%d\", ?8)", budget.name, budget.budget, budget.customDate, budget.customDay, budget.rolloverP, budget.rolloverN];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL);
sqlite3_bind_blob(statement, 8, [budget.purchases bytes], [budget.purchases length], SQLITE_TRANSIENT);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
NSLog(#"Save Success");
}
return success;
}
I am assuming that the query is incorrect, but I may be wrong.
EDIT:
Here is how I am adding the database. Again, new entries are added and retrieved from the database just fine. Old entries are retrieved but will not update.
- (void) initDatabase
{
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString:
[docsDir stringByAppendingPathComponent:#"budget.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if([filemgr fileExistsAtPath:databasePath] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString sql_stmt = #"CREATE TABLE IF NOT EXISTS BUDGETS (";
sql_stmt = [sql_stmt stringByAppendingString:#"id INTEGER PRIMARY KEY AUTOINCREMENT, "];
sql_stmt = [sql_stmt stringByAppendingString:#"name TEXT, "];
sql_stmt = [sql_stmt stringByAppendingString:#"budget DOUBLE, "];
sql_stmt = [sql_stmt stringByAppendingString:#"customdate INTEGER, "];
sql_stmt = [sql_stmt stringByAppendingString:#"customday INTEGER, "];
sql_stmt = [sql_stmt stringByAppendingString:#"rolloverp INTEGER, "];
sql_stmt = [sql_stmt stringByAppendingString:#"rollovern INTEGER, "];
sql_stmt = [sql_stmt stringByAppendingString:#"purchases BLOB)"];
if (sqlite3_exec(database, [sql_stmt UTF8String], NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table BUDGETS");
}
else
{
NSLog(#"BUDGETS table created successfully");
}
sqlite3_close(database);
}
else
{
NSLog(#"Failed to open/create database");
}
}
}
ANOTHER QUESTION:
I also have a question on whether I am saving the purchases NSArray correctly or not. I assumed that this would work.
Make sure the Location your pointing to the SQlite data base is right.And before executing the query make sure the table is in open state and ready to the operation. Refer this code:
sqlite3_stmt *statement;
sqlite3 *cPDB;
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Data base path
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"cPDB.db"]];
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &cPDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"UPDATE USER_SESSION_INFO SET \"%#\" = \"%#\", synState = 'false' WHERE sessionName=\"%#\"",categoryTy,state,sessionName];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(cPDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if((sqlite3_step(statement)) != SQLITE_DONE)
NSLog(#"Not Updated");
else
{
NSLog(#"Succesfully updated row !");
return YES;
}
}
}
Found the problem. There were no single quotes around ?8 in the update statement. Well, its always the small problems. Thanks everyone!
Could someone be so kind as to fill in the few missing pieces of code below. I am struggling with executing an sqlite statement using sqlite3_step, iterating through each row of results and putting the data into a useable format.
Here is the code that creates the database (Database is only two colums)
// Check if database is setup, if not create it
NSString *documents_directory;
NSArray *directory_path;
// Get the documents directory
directory_path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documents_directory = [directory_path objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [documents_directory stringByAppendingPathComponent: #"weights.db"]];
NSFileManager *file_manager = [NSFileManager defaultManager];
// Create database if it doesn't already exist
if([file_manager fileExistsAtPath: databasePath ] == NO){
const char *database_path = [databasePath UTF8String];
if(sqlite3_open(database_path, &contactDB) == SQLITE_OK){
char *error_message;
const char *sql_statement = "CREATE TABLE IF NOT EXISTS RECORDED_WEIGHTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, WEIGHT TEXT, TIME TEXT)";
if(sqlite3_exec(contactDB, sql_statement, NULL, NULL, &error_message) != SQLITE_OK){
status.text = #"Failed to create table";
}
sqlite3_close(contactDB);
}else{
status.text = #"Failed to open/create database";
}
}
And here is the code I am trying to complete;
// Get info from database and load it.
const char *database_path = [databasePath UTF8String];
sqlite3_stmt *statement;
if(sqlite3_open(database_path, &contactDB) == SQLITE_OK){
NSString *SQLquery = [NSString stringWithFormat:#"SELECT * FROM RECORDED_WEIGHTS ORDER BY TIME DESC"];
const char *query_statement = [SQLquery UTF8String];
if(sqlite3_prepare_v2(contactDB, query_statement, -1, &statement, NULL) == SQLITE_OK){
// Please help me execute statement and get results into useable format here.
}
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
Thanks in advance.
You want to do something like this:
while(sqlite3_step(statement) == SQLITE_ROW)
{
// int value
int intValue = sqlite3_column_int(statement,fieldIndex);
// string value
NSString* stringValue;
if (sqlite3_column_type(dbps, fieldIndex) != SQLITE_NULL)
{
const char *c = (const char *)sqlite3_column_text(dbps, fieldIndex);
if (c)
{
stringValue = #(c);
}
}
... etc...
}
Look at the documents for the different column types. You can also look at different objective-c wrappers out there to get an idea of how to access the database.