iPHONE SDK- sqlite , how do i do an insert statement - iphone

i have a database that is in the documents directorys of the
Application/iPhoneSimulator/3.2/Applications/etc/Documents
I have this code under my method
databaseName = #"database.sql";
NSArray *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory.NSUserDomainMask,YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
How do i do an insert with a variable/ array .
Something like
"INSERT INTO TABLE (COLUMN) VALUES ('%#'),[appDelegate.variable objectAtIndex:0];

I insist you to go through this question.
First of all copy the database from main bundle to your application's document dir.
You can follow below code to implement it.
NSString *databaseFile=[[NSBundle mainBundle] pathForResource:kDataBaseName ofType:kDataBaseExt];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *dbPath=[basePath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#",kDataBaseName,kDataBaseExt]];
NSFileManager *fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:dbPath]){
[fm copyItemAtPath:databaseFile toPath:dbPath error:nil];
}
[fm release];
self.dataBasePath=dbPath;
I am supplying you directly my project code. Please add comment if any doubts.
I have added comments for the explanation.
// function with multiple arguments which is going to be used for inserting into table.
+(void)insertBuilding:(NSString*)BName streetNo:(NSInteger)streetNo streetName:(NSString*)streetName streetDir:(NSString*)streetDir muni:(NSString*)muni province:(NSString*)province bAccess:(NSString*)bAccess bType:(NSString*)bType amnity:(NSString*)amnity latitude:(NSString*)latitude longitude:(NSString*)longitude imageName:(NSString*)imageName {
// application delegate where I have saved my database path.
BuildingLocatorAppDelegate *x=(BuildingLocatorAppDelegate *)[[UIApplication sharedApplication]delegate];
sqlite3 *database; // database pointer
// verifying if database successfully opened from path or not.
// you must open database for executing insert query
// i have supplied database path in argument
// opened database address will be assigned to database pointer.
if(sqlite3_open([[x dataBasePath] UTF8String],&database) == SQLITE_OK) {
// creating a simple insert query string with arguments.
NSString *str=[NSString stringWithFormat:#"insert into buildingDtl(b_name,streetNo,streetName,streetDir,muni,province,b_access,b_type,aminity,latitude,longitude,b_image) values('%#',%i,'%#','%#','%#','%#','%#','%#','%#','%#','%#','%#')",BName,streetNo,streetName,streetDir,muni,province,bAccess,bType,amnity,latitude,longitude,imageName];
// converting query to UTF8string.
const char *sqlStmt=[str UTF8String];
sqlite3_stmt *cmp_sqlStmt;
// preparing for execution of statement.
if(sqlite3_prepare_v2(database, sqlStmt, -1, &cmp_sqlStmt, NULL)==SQLITE_OK) {
int returnValue = sqlite3_prepare_v2(database, sqlStmt, -1, &cmp_sqlStmt, NULL);
((returnValue==SQLITE_OK) ? NSLog(#"Success") : NSLog(#"UnSuccess") );
// if NSLog -> unsuccess - that means - there is some problem with insert query.
sqlite3_step(cmp_sqlStmt);
}
sqlite3_finalize(cmp_sqlStmt);
}
sqlite3_close(database);
// please don't forget to close database.
}

+(NSString *)stringWithFormat:(NSString *)format parameters:...];
NSString sql = [NSString stringWithFormat:#"INSERT INTO table VALUES('%#')", #"Hello, world!"];
sqlite3_....

Use either prepared statements in combination with the bind_*() functions (e.g. bind_text()) or the mprintf() function to insert strings, see this question for details.
To get a raw C-string you can pass to these functions use -UTF8String or -cStringUsingEncoding: on a NSString.

Related

UITableView not getting populated with sqlite database column

Here's the code of a method I used to populate UITableView with the contents of a column in sqlite database. However, this is giving no errors at run-time but still does not give any data in UITableView. If anyone could help, it'll be highly appreciated.
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"Strings List";
UITableViewCell *cell;
NSString *docsDir;
NSArray *dirPaths;
sqlite3_stmt *statement;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc]initWithString: [docsDir stringByAppendingPathComponent:#"strings.sqlite"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString * query =
#"SELECT string FROM strings";
const char * stmt = [query UTF8String];
if (sqlite3_prepare_v2(contactDB, stmt, -1,&statement, NULL)==SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *string = [[NSString alloc]initWithUTF8String:(const char*)sqlite3_column_text(statement, 0)];
cell.textLabel.text = string; }
}
else NSLog(#"Failed");
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
}
}
I recommend you to read through Table View Programming Guide.
Most of the sequence you put in the viewDidLoad normally is placed in
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath;
that pretty complex method u are using, when u have all the delegate methods for table view which is just like putting butter on bread.
Try My Answer from this Link
Let me know if it worked !!!!
Cheers
if You are using simulator for testing purpose then delete your previous build and install app again. It fetch SQL file from document directory. So please try this and let me know. Thanks
Have you check if the problem is with you tableview or database?
Are you able to fetch data from database?Check if you are missing any method to connect sqlite in code.

How to update a table in SQLite database in objective C?

I created a table named "dept" in sqlite manually that has username (as Varchar) and Password (as Integer).
I used the following code to update a table
NSString *database2=[[NSBundle mainBundle]pathForResource:#"deptDatabase" ofType:#"sqlite"];
NSString *databasePath2=[NSString stringWithFormat:#"%#",database2];
const char *dbPath=[databasePath2 UTF8String];
if (sqlite3_open(dbPath, &dbHandler)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update dept set password=1234 where username='suren'";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(dbHandler, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Executed");
}
}
sqlite3_close(dbHandler);
but the table seems to be not updating.
Can anyone pls tell me how to update the table by altering the above code.
Thanks in advance
You can't not update fils in the mainBundle, these files are readonly.
To make changes to the database, you will have to copy it to the document directory.
And use the database in the document directory and not the one in the main bundle.
Only use the one in the main bundle as a payload file to be copied to the document directory if there is not file there.
Why do you create a new string here:
NSString *database2=[[NSBundle mainBundle]pathForResource:#"deptDatabase" ofType:#"sqlite"];
NSString *databasePath2=[NSString stringWithFormat:#"%#",database2];
The database2 is same as databasePath2. You are only using up memory here.
copy file from bundle to documents directory
NSString *databaseName = #"YOUR DB NAME WITH EXTENSION";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success=[fileManager fileExistsAtPath:databasePath];
if (!success) {
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
then u can work in the path databasePath (documents directory)
const char *dbPath=[databasePath UTF8String];
if (sqlite3_open(dbPath, &dbHandler)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update dept set password=1234 where username='suren'";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(dbHandler, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Executed");
}
}
sqlite3_close(dbHandler);
hope it helps.. happy coding :)

Insert data in sqlite table dynamically not working

I want to insert the data in a SQLite table login when a button is clicked, the problem is that when I click on the register button data is getting stored in variable but not in database table, and When I try to statically pass the value the data will be insert but When i trying to dynamically store data then not work.
Here is my code. Please go through it and help to solve this issue.
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask ,YES);
path = [paths objectAtIndex:0];
dbName = [[NSString alloc] initWithString:[path stringByAppendingPathComponent:#"mnc.sqlite"]];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if([fileMgr fileExistsAtPath:dbName]== NO)
{
const char *dbPath = [dbName UTF8String];
if (sqlite3_open(dbPath,&connectionDB)==SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = " create table if not exists login(user_name text ,password text)";
if (sqlite3_exec(connectionDB,sql_stmt,NULL,NULL,&errMsg))
{
printf("\n fail to create table ");
}
sqlite3_close(connectionDB);
}
else
{
NSLog(#"fail to open create database");
}
}
[fileMgr release];
if(sqlite3_prepare_v2(connectionDB, query ,-1, &statment,NULL) == SQLITE_OK)
{
sqlite3_bind_text(statment,1,"cc", -1,SQLITE_TRANSIENT);
sqlite3_bind_text(statment,2,"sa",-1,SQLITE_TRANSIENT);
NSLog(#"aadd");
}
if (sqlite3_step(statment)== SQLITE_DONE)
{
NSLog(#"This should be real error checking!");
sqlite3_finalize(statment);
}
It is quite complex to work with sqlite, thats why I use fmdb this will simplify the work.
This is an Objective-c wrapper around SQLite
Hope this helps.

bind or column index out of range

I want to delete all data in an existing sqlite DB, this is the code i am using:
sqlite3* database;
databaseName = #"AppDB";
NSString *pathToDatabase;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
pathToDatabase = [documentsDir stringByAppendingPathComponent:databaseName];
int databaseReturnCode = sqlite3_open([pathToDatabase UTF8String], &database);
NSLog(#"databaseReturnCode %d",databaseReturnCode);
if(databaseReturnCode == SQLITE_OK) {
const char *sql = "delete from AppDB";
sqlite3_stmt *delete_statement;
sqlite3_prepare_v2(database, sql, -1, &delete_statement, NULL);
sqlite3_bind_int(delete_statement, 1, 1);
printf( "error or not an error? : %s\n", sqlite3_errmsg(database) );
sqlite3_reset(delete_statement);
sqlite3_finalize(delete_statement);
}
sqlite3_close(database);
there are more than one field and more than one table in this DB. Please let me know what the error is. Thanks in advance.
Please comment this sqlite3_bind_int(delete_statement, 1, 1); line and run the code, Because in query you do not have any parameter which will need binding. Also I wander does this query exists? can you do like this delete from someDatabase directly? I don't think there is any query which takes database name! (I hope AppDB is table name).
[We should follow standard naming conventions for easy understanding.]
Thanks

sqlite error :/* SQL error or missing database */

I have a project in which I stored sqlite database file "data.sqlite3" to
'Group'&files'-'resource'
Below are my viewcontroller source codes
//-myviewcontroller.h
#import "sqlite3.h"
#define kFilename #"data.sqlite3"
//myviewcontroller.m
-(NSString *)dataFilePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
-(void)f
{
if (sqlite3_open([[self dataFilePath] UTF8String],&database)!=SQLITE_OK)
//dataFilePath returns
///Users/interdev/Library/Application Support/iPhone Simulator/User/Applications/095C6E05-4EAE-4817-883E-A72E39D439E0/Documents/data.sqlite3
{
sqlite3_close(database);
NSAssert(0,#"Failed to open database");//no problem
}
NSString *query = #"SELECT * FROM table1 ORDER BY ROW";//table1 is table name
sqlite3_stmt *statement;
NSInteger v=sqlite3_prepare_v2( database, [query UTF8String],
-1, &statement, nil);
NSString *zs= [NSString stringWithFormat:#"%d",v];
NSLog(#" The buttontitile is %# ",zs);
if ( v == SQLITE_OK) { // ...
}
I checked value of v in log, it always is 1
#define SQLITE_ERROR 1 /* SQL error or missing database */
I do not know why this happened.
It looks like your code is looking for your database in the 'Documents' folder of your application.
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
Thus, if the data.sqlite3 file is in your Resources folder, the applicaiton is not going to find the database. It's probably best to create and store the sqlitedatabase in the 'Documents' folder of the applicaiton. E.g /Users/interdev/Library/Application Support/iPhone Simulator/User/Applications/095C6E05-4EAE-4817-883E-A72E39D439E0/Documents/data.sqlite3