Related
I would like to update some data in Xcode sqlite db. The db is successfully connected, but seems like there's something wrong in the sql statement, it keeps returning "Failed to add contact", thanks for helping.
- (void) saveData:(id)sender
{
NSLog(#"The code runs through here!");
sqlite3_stmt *statement;
NSString *documents = [self applicationDocumentsDirectory];
NSString *dbPath = [documents stringByAppendingPathComponent:#"monitorDB.sqlite"];
const char *dbpath = [dbPath cStringUsingEncoding:NSASCIIStringEncoding];
if (sqlite3_open(dbpath, & contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"UPDATE profile SET username = \"%#\" WHERE id = 1" ,
self.username.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
self.settingStatus.text = #"Contact added";
} else {
self.settingStatus.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
} else {
self.settingStatus.text = #"DB Not Connect";
}
}
Try like this..
In viewdidload we need to check wether table exist or not. If not we need to create db.
NSString *docsdir;
NSArray *dirpaths;
dirpaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsdir=[dirpaths objectAtIndex:0];
dabasePath=[NSString stringWithFormat:[docsdir stringByAppendingPathComponent:#"contact.db"]];
NSFileManager *filemgr= [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:dabasePath]==NO ) {
const char *dbpath=[dabasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB)== SQLITE_OK) {
char *error;
const char *sql_stmt="CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, ADDRESS TEXT, NAME TEXT, PHONE TEXT, IMAGE BLOB)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &error)!= SQLITE_OK) {
status.text=#"failed to create";
}
sqlite3_close(contactDB);
}
}
To save data try to use the following code.
-(IBAction)saveData:(id)sender{
sqlite3_stmt *statement;
const char *dbpath = [dabasePath UTF8String];
NSData *imagedata=UIImagePNGRepresentation(imageview.image);
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {
NSString *insertSql =[NSString stringWithFormat:#"INSERT INTO CONTACTS (name, address, phone, image) VALUES (\"%#\", \"%#\", \"%#\", ?) ", name.text, address.text, phone.text ];
// NSString *nam=name.text;
const char *insert_stmt = [insertSql UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
sqlite3_bind_blob(statement, 1, [imagedata bytes], [imagedata length], NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
status.text=#"contact added";
[self clearClick:nil];
}else{
status.text=#"failed to added";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
To update data try to use the following code.
-(IBAction)updateClick:(id)sender{
sqlite3_stmt *updateStmt;
const char *dbpath = [dabasePath UTF8String];
if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
const char *sql = "update contacts Set address = ?, phone = ?, image = ? Where name=?";
if(sqlite3_prepare_v2(contactDB, sql, -1, &updateStmt, NULL)==SQLITE_OK){
sqlite3_bind_text(updateStmt, 4, [name.text UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 1, [address.text UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 2, [phone.text UTF8String], -1, SQLITE_TRANSIENT);
NSData *imagedata=UIImagePNGRepresentation(imageview.image);
sqlite3_bind_blob(updateStmt, 3, [imagedata bytes], [imagedata length], NULL);
}
}
char* errmsg;
sqlite3_exec(contactDB, "COMMIT", NULL, NULL, &errmsg);
if(SQLITE_DONE != sqlite3_step(updateStmt)){
NSLog(#"Error while updating. %s", sqlite3_errmsg(contactDB));
}
else{
[self clearClick:nil];
}
sqlite3_finalize(updateStmt);
sqlite3_close(contactDB);
}
Check your sql query and change it like this.
NSString *insertSQL = [NSString stringWithFormat:
#"UPDATE profile SET username = '%#' WHERE id = 1" ,
self.username.text];
Or if you want to do using bind text.
if (sqlite3_open(dbpath, & contactDB) == SQLITE_OK)
{
const char *insert_stmt = "UPDATE profile SET username = ? WHERE id = 1";
if(sqlite3_prepare_v2(contactDB, insert_stmt,
-1, &statement, NULL)== SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [self.username.text UTF8String], -1, SQLITE_TRANSIENT);
}
if (sqlite3_step(statement) == SQLITE_DONE)
{
self.settingStatus.text = #"Contact added";
} else {
self.settingStatus.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
} else {
self.settingStatus.text = #"DB Not Connect";
}
Just check
in .h file NSString *databaseName;
NSString *databasePath;
and in .m file specify databaseName = #"Db name";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
-(void)save:(id)sender
{
[self checkAndCreateDatabase];
sqlite3 *contactDB;
sqlite3_stmt *updateStmt;
if(sqlite3_open([databasePath UTF8String], &contactDB) == SQLITE_OK)
{
NSString *querySql=[NSString stringWithFormat:
#"UPDATE profile SET username = \"%#\" WHERE id = 1" ,
self.username.text];
const char*sql=[querySql UTF8String];
if(sqlite3_prepare_v2(contactDB,sql, -1, &updateStmt, NULL) == SQLITE_OK)
{
if(SQLITE_DONE != sqlite3_step(updateStmt))
{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(contactDB));
}
else{
sqlite3_reset(updateStmt);
NSLog(#"Update done successfully!");
}
}
sqlite3_finalize(updateStmt);
}
sqlite3_close(contactDB);
}
-(void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
There are many possibilities check all of the below:
1) Initialize statement with nil
sqlite3_stmt *statement = nil;
2) Try below
if (sqlite3_prepare_v2(contactDB, insert_stmt,-1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
//Updated
}
}
else
{
NSLog(#"error is %s",sqlite3_errmsg(database));
}
Are you sure the dbPath is not in app bundle? We can't update db in the bundle.
sqlite3_prepare_v2() and sqlite3_step() will return an int.
You can find something you want in sqlite3.h.
Like #define SQLITE_BUSY 5 /* The database file is locked */ ...
And, why not use FMDB? You can find it easy on Github. (Link https://github.com/ccgus/fmdb )
I have this code in my viewWillAppear method:
sqlite3 *database;
if (sqlite3_open([[self dataFilePath] UTF8String], &database)
!= SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Failed to open database");
}
sqlite3_stmt *statement;
//why is this if statement failing?
if (sqlite3_prepare_v2(database, [sqlStatement UTF8String],
-1, &statement, nil) == SQLITE_OK) {
It passes the first if statement without entering (which is good). The 2nd if statement is the problem.
The sqlStatement is in the form of SELECT * FROM food WHERE foodType = 'fruit'
I don't understand why it's not getting into the if statement. Any help would be appreciated.
The problem ended up not being in the code, but in the way that I exported the sqlite file. It was a series on INSERT statements, not an actual table.
and make changes according to ur requirement...
-(void) readDataFromDatabase
{
chapterAry = [[NSMutableArray alloc] init];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:#"QuotesApp.sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
const char *sqlStatement ="select * from MsExcelTutorial";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
while(sqlite3_step(compiledStatement)==SQLITE_ROW)
{
NSNumber *chapterId = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 0)];
NSString *chapter = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *link = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *bookmark = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSMutableDictionary *dic = [[NSMutableDictionary alloc]initWithObjectsAndKeys:chapterId,#"chapterId",chapter,#"chapter",link,#"link",bookmark,#"bookmark", nil];
[chapterAry addObject:dic];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
NSString *DBPath = [ClsCommonFunctions GetDatabasePath];
if ([self OpenDBWithPath:DBPath])//Method to open database connection
{
//filesDB is database object
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select fileID,filePath from tblFiles where isUploadPending =1";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(filesDB, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// u Need to get data from database...
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
sqlite3_close(filesDB);
}
go through it it will work
- (UserInfo*)getCurrentUserInfo:(NSString*)userName
{
UserInfo *userInfo = [[UserInfo alloc]init];
sqlite3 *database;
sqlite3_stmt *selectstmt;
NSLog(#"userName:%#",userName);
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *sqlString = [NSString stringWithFormat:#"SELECT USER_LEVEL FROM USER_INFO WHERE USER_NAME = '%#'" , userName];
NSLog(#"getCurrentUserInfo:%#",sqlString);
const char *SqlCommand = [sqlString UTF8String];
if (sqlite3_prepare_v2(database, SqlCommand, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"success!");
while (sqlite3_step(selectstmt) == SQLITE_ROW) {
NSString *userInfoStr = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
NSLog(#"select result:%#",userInfoStr);
}
}
sqlite3_finalize(selectstmt);
}
sqlite3_close (database);
return userInfo;
}
the following is my log output:
2012-03-06 17:50:11.556 MagicWords[508:f803] userName:Tan
2012-03-06 17:50:11.557 MagicWords[508:f803] getCurrentUserInfo:SELECT USER_LEVEL FROM USER_INFO WHERE USER_NAME = 'Tan'
It doesn't print "success",so sqlite3_prepare_v2 don't return yes.but my database is ok:
I can't find the problem?
Add sqlite error message . It will give an insight of what is going on inside. If all about your database is correct ,check the table name.
UserInfo *userInfo = [[UserInfo alloc]init];
sqlite3 *database;
sqlite3_stmt *selectstmt;
NSLog(#"userName:%#",userName);
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *sqlString = [NSString stringWithFormat:#"SELECT USER_LEVEL FROM USER_INFO WHERE USER_NAME = '%#'" , userName];
NSLog(#"getCurrentUserInfo:%#",sqlString);
const char *SqlCommand = [sqlString UTF8String];
if (sqlite3_prepare_v2(database, SqlCommand, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"success!");
while (sqlite3_step(selectstmt) == SQLITE_ROW) {
NSString *userInfoStr = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
NSLog(#"select result:%#",userInfoStr);
}
}
//Add the error message here.
else
{
NSLog(#"%s",sqlite3_errmsg(database));
}
///////
sqlite3_finalize(selectstmt);
}
sqlite3_close (database);
return userInfo;
Remove the quotes inside ' ' and Use Semicolon at the end of the sqlString.
NSString *sqlString = [NSString stringWithFormat:#"SELECT USER_LEVEL FROM USER_INFO WHERE USER_NAME = %#;" , userName];
try this when you are converting sqlString to char
const char *SqlCommand = (char *)[sqlString
cStringUsingEncoding:NSUTF8StringEncoding];
I made iPad application in which,
I want to insert record into database table, but I am unable to do the same.
here is my code snippet,
-(void) insertRecordIntoTableNamed: (NSString *) symbol{
NSString *sql = [NSString stringWithFormat:#"INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('%#',datetime())",symbol];
NSLog(#"sql=%#",sql);
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK)
{
sqlite3_close(db);
NSAssert(0, #"Error updating table.");
}
}
my NSLog shows:
sql=INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('PATNI',datetime())
this statement is correct, but i am unable to see VALUES PATNI and datetime() in my database table
here is rest of the code,
NSString *filePahs = Nil;
-(NSString *) filePath {
filePahs=[[NSBundle mainBundle] pathForResource:#"companymaster" ofType:#"sql"];
NSLog(#"path=%#",filePahs);
return filePahs;
}
result of above method is:
path=/Users/krunal/Library/Application Support/iPhone Simulator/5.0/Applications/9FF61238-2D1D-4CB7-8E24-9AC7CE9415BC/iStock kotak.app/companymaster.sql
-(void) openDB {
//---create database---
if (sqlite3_open([[self filePath] UTF8String], &db) != SQLITE_OK )
{
sqlite3_close(db);
NSAssert(0, #"Database failed to open.");
}
}
-(void) getAllRowsFromTableNamed: (NSString *) tableName {
//---retrieve rows---
NSString *qsql = #"SELECT * FROM recentquotes";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2( db, [qsql UTF8String], -1, &statement, nil) ==
SQLITE_OK) {
NSLog(#"b4 while");
while (sqlite3_step(statement) == SQLITE_ROW)
{
char *field1 = (char *) sqlite3_column_text(statement, 0);
NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];
[recentqotarray addObject:field1Str];
[field1Str release];
}
//---deletes the compiled statement from memory---
sqlite3_finalize(statement);
NSLog(#"recentqotarray=%#",recentqotarray);
}
}
edit
i wrote this, and when i checked my log i got like this, "in find data" , i didn't got my sql=...
- (void) finddata
{
NSString *databasePath;
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
NSLog(#"in finddata");
if (sqlite3_open(dbpath, &db) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT * FROM recentquotes"];
NSLog(#"sql=%#",querySQL);
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"Inside recent quote table");
char *field1 = (char *) sqlite3_column_text(statement, 0);
NSLog(#"Column name=%s",field1);
NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];
[recentqotarray addObject:field1Str];
NSLog(#"array=%#",recentqotarray);
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
}
}
Thanks In Advance
In your:
NSString *sql = [NSString stringWithFormat:#"INSERT INTO recentquotes ('symbol', 'dt_tm') VALUES ('%#',datetime())",symbol];
Instead of '%#' try using \"%#\" , and check if it inserts into your db.
EDIT:
I've been working on DB a lot lately, and i've been able to successfully insert data in my sqlite, i'll write down what i use check if it helps:
NSArray*dirPath;
NSString*docDir;
dirPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docDir=[dirPath objectAtIndex:0];
databasePath=[docDir stringByAppendingPathComponent:#"example.sqlite"];
BOOL success;
NSFileManager*fm=[NSFileManager defaultManager];
success=[fm fileExistsAtPath:databasePath];
if(success)
{
NSLog(#"Already present");
}
NSString*bundlePath=[[NSBundle mainBundle] pathForResource:#"example" ofType:#"sqlite"];
NSError*error;
success=[fm copyItemAtPath:bundlePath toPath:databasePath error:&error];
if(success)
{
NSLog(#"Created successfully");
}
const char*dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &myDB)==SQLITE_OK)
{
NSString*insertSQL=[NSString stringWithFormat:#"insert into extable (name) values (\"%#\")",[nametextField.text]];
const char*insertStmt=[insertSQL UTF8String];
char *errmsg=nil;
if(sqlite3_exec(myDB, insertStmt, NULL, NULL, &errmsg)==SQLITE_OK)
{
NSLog(#"ADDED!");
}
sqlite3_close(myDB);
}
im trying to integrate a database into my project.This is for first time im implementing a database project.I integrated the database into my project.Database has 3 columns named rowid,col1,col2.Below code i used for acessing the datafrom database.But it is not enetering in "if loop"Can anyone help me where im doing wrong in this case.Thanks in advance.![enter image description here][1]
/* -(void)print
{
sqlite3_stmt *statement;
qsql=[NSString stringWithFormat:#"SELECT * from light where rowid = '%d'",1];
if(sqlite3_prepare_v2(database, [qsql UTF8String], -1, &statement, NULL) == SQLITE_OK) {
NSLog(#"hhhhhhhhh");
while (sqlite3_step(statement) == (SQLITE_ROW)){
NSString *Q_NO = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
// tv.text=qsql;
}
}}*/
-(void)print
{
sqlite3_stmt *statement;
//qsql=[NSString stringWithFormat:#"SELECT * from light where rowid = %d",1];
qsql=[NSString stringWithFormat:#"SELECT * from light where rowid = %i",1];
//const char *sqlStatement = [qsql cStringUsingEncoding:NSUTF8StringEncoding];
const char *qsql_stament = [qsql cStringUsingEncoding:NSUTF8StringEncoding];
if(sqlite3_prepare_v2(database, qsql_stament, -1, &statement, NULL) == SQLITE_OK) {
NSLog(#"hhhhhhhhh");
while (sqlite3_step(statement) == (SQLITE_ROW)){
// NSString *Q_NO = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSString *Q_NO = [[NSString alloc] initWithString:[NSString stringWithFormat:#"%i",sqlite3_column_int(statement, 0)]];
// tv.text=qsql;
}
}
}
-(void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
[fileManager release];
}
-(void) openDB {
databaseName = #"Lighthr.sqlite";
NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentsPaths objectAtIndex:0];
databasePath = [documentDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
if(sqlite3_open([databasePath UTF8String],&database) == SQLITE_OK){
NSLog(#"coming here???");
}
}
[1]: http://i.stack.imgur.com/lm1ZV.png
because rowid is always integer and you are trying to access using string.
I thing you have to try this.
Edit
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
qsql=[NSString stringWithFormat:#"SELECT * from light where rowid = %i",1];
const char *sqlStatement = [qsql cStringUsingEncoding:NSUTF8StringEncoding];
if(sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {
NSLog(#"hhhhhhhhh");
while (sqlite3_step(statement) == (SQLITE_ROW)){
NSString *Q_NO = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
// tv.text=qsql;
}
}
}
Are you trying to test without your "where" clause ?
And what is the error code return by sqlite3_prepare_v2 ?
int sql_answer = sqlite3_prepare_v2(database, qsql_stament, -1, &statement, NULL);
NSLog(#" SQL answer : %d",sql_answer );
if(sql_answer == SQLITE_OK) {
...
i think you should do in this way .
-(void)print
{
sqlite3_stmt *statement;
qsql=[NSString stringWithFormat:#"SELECT * from light where rowid = %d",1];
const char *qsql_stament = [qsql cStringUsingEncoding:NSUTF8StringEncoding];
if(sqlite3_prepare_v2(database, qsql_stament, -1, &statement, NULL) == SQLITE_OK) {
NSLog(#"hhhhhhhhh");
while (sqlite3_step(statement) == (SQLITE_ROW)){
NSString *Q_NO =[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]
}
NSString *Q_NO = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
above stameny replace with below statement
NSString *Q_NO = [[NSString alloc] initWithString:[NSString stringWithFormat:#"%i",sqlite3_column_int(statement, 0)]];
and
const char *qsql_stament = [qsql cStringUsingEncoding:NSUTF8StringEncoding];
now replace [qsql UTF8String] with qsql_stament. It will work fine.