This is my code.
It is only returning the first row from database. I know something is really wrong but don't know what. Please help.
if(sqlite3_open([databasePath UTF8String],&texttalkdb)==SQLITE_OK)
{
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(texttalkdb, [sql UTF8String], -1,&statement, NULL)==SQLITE_OK)
{
if(sqlite3_step(statement)==SQLITE_ROW)
{
for(int i=0;i<=20;i++)
{
char *pass=(char*)sqlite3_column_text(statement,i);
NSString *passStr = [NSString stringWithFormat:#"%s",pass];
NSString *msg=[[NSString alloc]initWithUTF8String:pass];
[arr addObject:msg];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(texttalkdb);
}
NSLog(#"%#",arr);
return arr;
Try this
if(sqlite3_prepare_v2(texttalkdb, [sql UTF8String], -1,&statement, NULL)==SQLITE_OK)
{
while( sqlite3_step(statement) == SQLITE_ROW )
{
//get records
}
}
Step 1: This is for check the getting values is empty or not
+(NSString*)charToString:(char*)chart
{
NSString *string = #" ";
if(string)
{
chart = [self checkEmptyChar:chart];
string=[NSString stringWithUTF8String:chart];
}
return string;
}
Step 2: This is for checking character
+(char *)checkEmptyChar:(char *)check
{
NSString *string = #" ";
if (check == NULL)
check = string;
return check;
}
Step 3: To fetch SQLite Coding
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &stment, nil) == SQLITE_OK)
{
while (sqlite3_step(stment) == SQLITE_ROW)
{
for(int i=0;i<=20;i++)
{
NSString *msg = [self charToString: (char *)sqlite3_column_text(stment, i)];
[array addObject:msg];
}
}
sqlite3_reset(stment);
}
sqlite3_finalize(stment);
}
sqlite3_close(database);
Related
My question is how to insert a fetched JSON array data into sqlite database.
I have fetched JSON data which is an array of dictionaries.
My code to save JSON result looks like this:
-(BOOL) saveApiResults: (NSString *)tableName : (NSArray *)data
{
BOOL saveSuccess = NO;
#try {
const char *dbPath = [databasePath UTF8String];
if(sqlite3_open(dbPath,&database)==SQLITE_OK) {
sqlite3_exec(database, "BEGIN", 0, 0, 0);
//pass an array containing json dictionary to below line
NSDictionary *rowData=[data objectAtIndex:0];
NSArray *keyArray = [rowData allKeys];
NSLog(#"key array %#",keyArray);
NSString *insertSQL=#"INSERT INTO ";
insertSQL=[insertSQL stringByAppendingString:#"moodsdata"];
insertSQL=[insertSQL stringByAppendingString:#" VALUES("];
for(int j=0;j<[keyArray count];j++)
{
insertSQL=[insertSQL stringByAppendingString:#"?"];
if(j<[keyArray count]-1)
insertSQL=[insertSQL stringByAppendingString:#","];
}
insertSQL=[insertSQL stringByAppendingString:#");"];
NSLog(#"query : %# ",insertSQL);
const char *sqlstatement = [insertSQL UTF8String];
sqlite3_stmt *compiledstatement;
if(sqlite3_prepare_v2(database,sqlstatement , -1, &compiledstatement, NULL)==SQLITE_OK) {
for (NSUInteger i = 0; i < [data count]; i++) {
NSDictionary *rowData=[data objectAtIndex:0];
for(int j=0;j<[keyArray count];j++) {
NSString *val = #"";
NSString *value=(NSString *)[rowData objectForKey:[keyArray objectAtIndex:j]];
if((value != nil) && (![value isEqual:[NSNull null]]))
val=[NSString stringWithFormat:#"%#",value];
NSLog(#"values %#",val);
sqlite3_bind_text(compiledstatement,j+1,[val UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiledstatement) != SQLITE_DONE) {
NSLog(#"ERROR");
}
sqlite3_clear_bindings(compiledstatement);
sqlite3_reset(compiledstatement);
}
sqlite3_exec(database, "COMMIT", 0, 0, 0);
saveSuccess = YES;
NSLog(#"RESULTS SAVED SUCCESSFULLY!");
} else {
NSLog(#"StatemenT FAILED (%s)", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledstatement);
} else {
NSLog(#"Statement FAILED (%s)", sqlite3_errmsg(database));
}
}
#catch (NSException *exception) {
NSLog(#"NSException : %#",exception.description);
}
#finally {
sqlite3_close(database);
}
return saveSuccess;
}
My question is when I try to pass the JSON array to this method it only saves the value for first array object . i.e. only first dictionary values get saved. Please tell me what I am doing wrong.
You primary issue is that you mistakenly access data[0] instead of data[i] in your loop that does the actual inserting.
But there are lots of other little issues with this code. Here's your code all cleaned up:
-(BOOL) saveApiResults:(NSString *)tableName data:(NSArray *)data
{
BOOL saveSuccess = NO;
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open(dbPath,&database) == SQLITE_OK) {
sqlite3_exec(database, "BEGIN", 0, 0, 0);
//pass an array containing json dictionary to below line
NSDictionary *rowData = data[0];
NSArray *keyArray = [rowData allKeys];
NSLog(#"key array %#",keyArray);
NSMutableString *insertSQL = #"INSERT INTO moods data VALUES(";
for (NSInteger j = 0; j < [keyArray count]; j++)
{
if (j) {
[insertSQL appendString:#","];
}
[insertSQL appendString:#"?"];
}
[insertSQL appendString:#");"];
NSLog(#"query : %# ",insertSQL);
const char *sqlstatement = [insertSQL UTF8String];
sqlite3_stmt *compiledstatement;
if (sqlite3_prepare_v2(database, sqlstatement, -1, &compiledstatement, NULL) == SQLITE_OK) {
for (NSDictionary *rowData in data) {
for (NSInteger j = 0; j < [keyArray count]; j++) {
NSString *val = #"";
NSString *value = rowData[keyArray[j];
if (value && ![value isEqual:[NSNull null]]) {
val = [NSString stringWithFormat:#"%#",value];
}
NSLog(#"values %#",val);
sqlite3_bind_text(compiled statement, j + 1, [val UTF8String], -1, SQLITE_TRANSIENT);
}
if (sqlite3_step(compiledstatement) != SQLITE_DONE) {
NSLog(#"ERROR");
}
sqlite3_reset(compiledstatement);
}
sqlite3_exec(database, "COMMIT", 0, 0, 0);
sqlite3_finalize(compiledstatement);
saveSuccess = YES;
NSLog(#"RESULTS SAVED SUCCESSFULLY!");
} else {
NSLog(#"StatemenTtFAILED (%s)", sqlite3_errmsg(database));
}
sqlite3_close(database);
} else {
NSLog(#"Statement FAILED (%s)", sqlite3_errmsg(database));
}
return saveSuccess;
}
There is no need for try/catch. Just do proper error checking.
Use NSMutableString to build up a string piece by piece.
Only finalize a statement if you successfully prepare it.
Be sure to close a database if you open it.
Use modern syntax for accessing values from dictionaries and arrays. It's easier to read and type.
Use modern loops when possible.
Use whitespace. It makes the code easier to read.
Give all of your method parameters a name.
But your SQLite code was actually better than most posts here. You actually use sqlite_bind_xxx to bind values to your query. Too few people do that.
In your code where you're grabbing the values, you are grabbing the row data with:
NSDictionary *rowData=[data objectAtIndex:0];
I suspect you mean:
NSDictionary *rowData=[data objectAtIndex:i];
I want execute the insert query the query was working fine when we call this InsUpdateDelData its return false then the data was not inserted
- (IBAction)addToCart:(id)sender {
AppDelegate *obj = (AppDelegate *)[[UIApplication sharedApplication]delegate] ;
NSString *insert = #"ahmadyarimran#yahoo.com" ;
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO cart_user(user_id,product_price,product_type,categories_type,product_images,description) values('%#','%#','%#','%#','%#','%#')",insert,handBegsImages.product_price,handBegsImages.product_tagline,handbegCategoriess.handbegid,handBegsImages.main_image,handBegsImages.product_description];
BOOL abc = [obj InsUpdateDelData:insertSQL];
NSLog(#"print the value of abc %#=", abc) ;
if (abc == TRUE) {
NSLog(#"# Data was Inserted");
}
else{
[Utility showAlertView:#"Plz try again message" message:#"Again" viewcontroller:self];
}
}
-(BOOL)InsUpdateDelData:(NSString*)SqlStr
{
if([SqlStr isEqual:#""])
return NO;
BOOL RetrunValue;
RetrunValue = NO;
const char *sql = [SqlStr cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK)
RetrunValue = YES;
if(RetrunValue == YES)
{
if(sqlite3_step(stmt) != SQLITE_DONE) {
}
sqlite3_finalize(stmt);
}
return RetrunValue;
}
If InsUpdateDelData returned NO, then that means that sqlite3_prepare_v2 did not return SQLITE_OK. If you want to know why it did not return SQLITE_OK, then log the error immediately after sqlite3_prepare_v2 failed, but before calling any other SQLite functions:
NSLog(#"err=%s", sqlite3_errmsg(database));
I have a table in a database which I access like this:
+(NSMutableArray *) queryDatabaseWithSQL:(NSString *)sql params:(NSArray *)params {
sqlite3 *database;
NSMutableArray *rtn = [[NSMutableArray alloc] init];
int index = 0;
NSString *filepath = [self copyDatabaseToDocumentsWithName:#"database"];
if (sqlite3_open([filepath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = [sql cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
if ([params count]) {
for (int i = 0; i < [params count]; i++) {
NSString *obj = [params objectAtIndex:i];
sqlite3_bind_blob(compiledStatement, i + 1, [obj UTF8String], -1, SQLITE_TRANSIENT);
}
}
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSMutableArray *arr = [[NSMutableArray alloc] init];
index = 0;
const char *s = (char *)sqlite3_column_text(compiledStatement, index);
while (s) {
[arr addObject:[NSString stringWithUTF8String:s]];
index++;
s = (char *)sqlite3_column_text(compiledStatement, index);
}
if (![rtn containsObject:arr]) {
[rtn addObject:arr];
}
}
}
sqlite3_finalize(compiledStatement);
}
NSLog(#"ERROR: %s", sqlite3_errmsg(database));
sqlite3_close(database);
return rtn;
}
This works fine when I call the function like this:
NSLog(#"%#", [database queryDatabaseWithSQL:#"SELECT * FROM FRIENDSUSERS WHERE USER = ?" params:#[[delegate->user objectForKey:#"username"]]]);
Then when I call the function using a string like this it doesn't return any rows:
NSLog(#"%#", [database queryDatabaseWithSQL:#"SELECT * FROM FRIENDSUSERS WHERE USER = ?" params:#[#"username"]]);
I haven't got a clue what is going one with but I have checked the strings match and they do so I'm now stuck
Can anyone see any reason why this would not work
I have run error checks as well and every time it returns no error, or rows :(
Thanks in advance
- (void) updateTimeStamp:(NSDictionary *) record forRowID: (NSString *) updateTableName
{
int dictionarySize = [record count];
NSMutableData *dKeys = [NSMutableData dataWithLength:sizeof(id) *dictionarySize];
NSMutableData * dValues = [NSMutableData dataWithLength: sizeof(id) * dictionarySize];
[record getObjects:(__unsafe_unretained id *)dValues.mutableBytes andKeys:(__unsafe_unretained id *)dKeys.mutableBytes];
[dValues appendBytes:&updateTableName length:sizeof(id)];
NSString * query = [NSString stringWithFormat:#"update %# set %# = ? where Table_Name= ?",tableName,[[record allKeys] componentsJoinedByString:#" = ?, "]];
[self bindSQL:[query UTF8String] withVargs:(va_list)dValues.mutableBytes];
if(sqlite3_step(statment) == SQLITE_DONE);
{
NSLog(#"prepead Timestamp %s",sqlite3_errmsg(database));
}
sqlite3_reset(statment);
#synchronized(self)
{
if(sqlite3_finalize(statment) != SQLITE_OK)
{
NSLog(#"doQuery: sqlite3_finalize failed (%s)", sqlite3_errmsg(database));
}
}
}
When i run application that function work perfectly? not an any issue but that function after database is locked ? what the problem with the function please give me solution
i have many table so i open database once time in function when all timestamp updated after close the database.
bindSQL function below
- (void) bindSQL:(const char *) cQuery withVargs:(va_list)vargs
{
int param_count;
NSLog(#"%d",sqlite3_prepare_v2(database, cQuery, -1, &statment, NULL));
if(sqlite3_prepare_v2(database, cQuery, -1, &statment, NULL) != SQLITE_OK)
{
NSLog(#"bindSQL: could not prepare statement (%s) %s", sqlite3_errmsg(database), cQuery);
statment = NULL;
return;
}
if((param_count = sqlite3_bind_parameter_count(statment)))
{
for(int i =0; i < param_count ;i++)
{
id object = va_arg(vargs,id);
if(object == nil)
{
sqlite3_bind_null(statment, i+1);
}
else if ([object respondsToSelector:#selector(objCType)])
{
if(strchr("islqISLBQ", *[object objCType]))
{
sqlite3_bind_int(statment, i+1, [object intValue]);
}
else if (strchr("fd", *[object objCType]))
{
sqlite3_bind_double(statment, i+1, [object doubleValue]);
}
else
{
NSLog(#"bindSQL: Unhandled objCType: %s query: %s", [object objCType], cQuery);
statment = NULL;
return;
}
}
else if ([object respondsToSelector:#selector(UTF8String)])
{
sqlite3_bind_text(statment, i+1, [object UTF8String], -1, SQLITE_TRANSIENT);
}
else if ([object isEqual:[NSNull null]])
{
statment = NULL;
return;
}
else
{
NSLog(#"bindSQL: Unhandled parameter type: %# query: %s", [object class], cQuery);
statment = NULL;
return;
}
}
}
va_end(vargs);
return;
}
This code creates two statement objects:
NSLog(#"%d",sqlite3_prepare_v2(database, cQuery, -1, &statment, NULL));
if(sqlite3_prepare_v2(database, cQuery, -1, &statment, NULL) != SQLITE_OK)
of which only one is finalized later.
If you want to check the return code, better use a variable:
int rc = sqlite3_prepare_v2(database, cQuery, -1, &statment, NULL);
NSLog(#"%d", rc);
if (rc != SQLITE_OK)
How to retrieve data from sqlite database? Getting return value zero.
-(id)init{
if(self==[super init]){
database=nil;
}
return self;
}
-(void)addDetails:(NSString *)_name withAddress:(NSString *)_address withAge:(int)_age withMobile:(double)_mobile{
// NSLog(#"in db class --->%# %# %d %f",_name,_address,_age,_mobile);
// NSString *name=#"...has done it";
if([self openDBConnection] == TRUE) {
const char *sql= "insert into Personal (Name,Address,Age,Mobiel) Values(?, ?, ?, ?)";
sqlite3_stmt *updateUser_stmt = nil;
NSInteger retVal = sqlite3_prepare_v2(database, sql, -1, &updateUser_stmt, NULL);
NSLog(#"the return value is %d",retVal);
if(retVal == SQLITE_OK)
{
sqlite3_bind_text (updateUser_stmt , 1, [_name UTF8String],-1,SQLITE_STATIC);
sqlite3_bind_text (updateUser_stmt , 2, [_address UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int(updateUser_stmt, 3, _age);
sqlite3_bind_double(updateUser_stmt, 4, _mobile);
// sqlite3_bind_text (updateUser_stmt , 4, [HomeUserDetails.strName UTF8String], -1, SQLITE_STATIC);
NSInteger resultInt = sqlite3_step(updateUser_stmt );
if(SQLITE_DONE != resultInt)
NSLog(#"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
{
NSLog(#"MyA user details added to database");
}
}
sqlite3_reset(updateUser_stmt );
sqlite3_finalize(updateUser_stmt );
updateUser_stmt = nil;
}
}
-(void) modifyUserDetails :(Person *)_person
{
NSLog(#"in update");
if([self openDBConnection] == TRUE)
{
NSString *str = [NSString stringWithFormat:#"UPDATE Personal SET Address='%#', Age='%d' , Mobiel='%d' WHERE Name='%#'",
_person.address, [_person getAge], [_person getMobile], _person.name];
NSLog(#" String :%#",str);
//NSString *str = [NSString stringWithFormat:#"UPDATE Room SET Access=1 WHERE RoomName='%#'",room.m_roomName];
const char *sql = [str UTF8String];
// [NSString stringWithFormat:#"UPDATE Room SET Access=%d WHERE RoomName=%#", access,room.m_roomName];
sqlite3_stmt *updateUser_stmt = nil;
if(sqlite3_prepare_v2(database, sql, -1, &updateUser_stmt, NULL) == SQLITE_OK)
{
sqlite3_bind_text(updateUser_stmt, 1, [_person.name UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(updateUser_stmt, 2, [_person.address UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int(updateUser_stmt, 3, [_person getAge]);
sqlite3_bind_double(updateUser_stmt, 4, [_person getMobile]);
if(SQLITE_DONE != sqlite3_step(updateUser_stmt))
NSLog(#"Error while updating data data. '%s'", sqlite3_errmsg(database));
}
sqlite3_reset(updateUser_stmt );
sqlite3_finalize(updateUser_stmt );
updateUser_stmt = nil;
}
}
-(void)getUserDetails
{
UIApplication *app=[UIApplication sharedApplication];
appdlegate=app.delegate;
if(appdlegate.arrayNames)
[appdlegate.arrayNames removeAllObjects];
NSLog(#"in get users");
if([self openDBConnection] == TRUE)
{
const char *sql = "select Name,Address,Age,Mobiel from Personal";//AccessLevel,HintA HintQ,Name,pwd
sqlite3_stmt *getAccess_stmt = nil;
NSInteger retVal = sqlite3_prepare_v2(database, sql, -1, &getAccess_stmt, NULL);
if(retVal == SQLITE_OK)
{
while(sqlite3_step(getAccess_stmt) == SQLITE_ROW)
{
char* name = (char*) sqlite3_column_text(getAccess_stmt, 0);
NSString *tmp;
if (name != NULL){
tmp = [NSString stringWithUTF8String:name];
NSLog(#"value form db :%#",tmp);
}
[appdlegate.arrayNames addObject:tmp];
char *addrs = (char*) sqlite3_column_text(getAccess_stmt, 1);
if (addrs != NULL){
NSString *tmp = [NSString stringWithUTF8String:addrs];
NSLog(#"value from db :%#",tmp);
}
int age =sqlite3_column_int(getAccess_stmt,2);
if(age){
NSLog(#"age from db: %d",age);
}
int mobile=sqlite3_column_double(getAccess_stmt, 3);
;
if(mobile){
NSLog(#"mobile from db: %d",mobile);
}
}
}
sqlite3_reset(getAccess_stmt );
sqlite3_finalize(getAccess_stmt );
getAccess_stmt = nil;
}
}
-(Person *)getPerticular:(NSString *)_name
{
Person *person;
UIApplication *app=[UIApplication sharedApplication];
appdlegate=app.delegate;
NSLog(#"in get users");
if([self openDBConnection] == TRUE)
{
NSString *query = [NSString stringWithFormat:#"select *from Personal where name ='%#'",_name];
const char *sql =[query cStringUsingEncoding:NSASCIIStringEncoding];
//const char *sql = "select *from Personal where name=''";//AccessLevel,HintA HintQ,Name,pwd
sqlite3_stmt *getAccess_stmt = nil;
NSInteger retVal = sqlite3_prepare_v2(database, sql, -1, &getAccess_stmt, NULL);
if(retVal == SQLITE_OK)
{
person=[[Person alloc]init];
while(sqlite3_step(getAccess_stmt) == SQLITE_ROW)
{
char* name = (char*) sqlite3_column_text(getAccess_stmt, 0);
NSString *tmp;
if (name != NULL){
tmp = [NSString stringWithUTF8String:name];
NSLog(#"value perticular form db :%#",tmp);
person.name=tmp;
}
char *addrs = (char*) sqlite3_column_text(getAccess_stmt, 1);
if (addrs != NULL){
NSString *tmp = [NSString stringWithUTF8String:addrs];
NSLog(#"value perticular from db :%#",tmp);
person.address=tmp;
}
int age =sqlite3_column_int(getAccess_stmt,2);
if(age){
NSLog(#"perticular age from db: %d",age);
[person setAge:age];
}
int mobile=sqlite3_column_double(getAccess_stmt, 3);
;
if(mobile){
NSLog(#"mobile from db: %d",mobile);
[person setMobile:mobile];
}
}
}
sqlite3_reset(getAccess_stmt );
sqlite3_finalize(getAccess_stmt );
getAccess_stmt = nil;
}
return person;
}
-(void)createConnection{
NSError *error;
NSArray *strdest=[NSArray arrayWithObjects:NSHomeDirectory(),#"Documents",DB_NAME,nil];
dest=[NSString pathWithComponents:strdest];
NSFileManager *manager=[NSFileManager defaultManager];
NSArray *strSrc=[NSArray arrayWithObjects:NSHomeDirectory(),#"SqlliteDemo.app",DB_NAME, nil];
NSString *source=[NSString pathWithComponents:strSrc];
BOOL sucess=[manager fileExistsAtPath:dest];
if(sucess){
NSLog(#"alredy db copied to documents");
}
else {
[manager copyItemAtPath:source toPath:dest error:&error];
if(error){
NSLog(#"NO Error");
}
else{
NSLog(#"error is %#",error);
}
}
}
-(BOOL)openDBConnection{
[self createConnection];
if(!database){
if(sqlite3_open([dest UTF8String], &database)==SQLITE_OK){
return TRUE;
}else {
return FALSE;
}
}
return TRUE;
}
-(void)finalizeStatements{
if(database)sqlite3_close(database);
}
Think so there is some problem in your Query shown below, please cross check the same query in the command line. Even see if u have properly added the db file in ur project, that too may create some problem.
NSString *query = [NSString stringWithFormat:#"select *from Personal where name ='%#'",_name];