0

data could not be fetched when selected from sqlite database , and showing error of [NSPlaceholderString initWithUTF8String:]: NULL cString' , at step function .

... i am mentioning all the steps which i have followed to perform this operation . so correct me if i am wrong at some procedure .

i have created database.sqlite file ,inside table news_array with 4 column (N_id, N_Title , N_Desc ,N_img ) ,from sqlite manager and saved it . then i drag and dropped the .sqlite file into project . added libsqlite3.tbd and imported sqlite3.h .

then in .m file , i created insert operation and tried to insert array data into the database .

-(void)insert
NSArray *documentPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDir = [documentPaths objectAtIndex:0];

NSString *databasePath = [documentsDir stringByAppendingPathComponent:@"Database.sqlite"];

NSString *databasePathFromApp = [ [ [NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Database.sqlite"];

NSFileManager *fileManager = [NSFileManager defaultManager];

if ( ![ fileManager fileExistsAtPath:databasePathFromApp ] )

    return;

[ fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil ];

sqlite3 *database;

if (sqlite3_open( [databasePath UTF8String], &database) == SQLITE_OK)
{
    for (int i = 0; i < 10 ; i++)
    {
 NSString * nwsid = [[arrydata_tbl objectAtIndex:i]objectForKey:@"NewsId"];
int myInt = [nwsid intValue];
NSString * nwsttl = [[arrydata_tbl objectAtIndex:i]objectForKey:@"NewsTitle"];
NSString * nwsdesc = [[arrydata_tbl objectAtIndex:i]objectForKey:@"NewsDescription"];
        NSData * nwsimg = [[arrydata_tbl objectAtIndex:i]objectForKey:@"NewsImage"];

         const char *insert_stmt ="INSERT INTO news_array (N_id, N_Title , N_Desc ,N_img )VALUES (?,?,?,?);";
        sqlite3_stmt *compiledStatement;

        sqlite3_prepare_v2(database, insert_stmt,-1, &compiledStatement, NULL) ;

        {
            sqlite3_bind_int(compiledStatement, 1, myInt);
sqlite3_bind_text(compiledStatement, 2, [nwsttl UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 3, [nwsdesc UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_blob (compiledStatement, 4, [nwsimg bytes], (int)[nwsimg length], SQLITE_TRANSIENT);

if (sqlite3_step(compiledStatement) == SQLITE_DONE)

        {
            NSLog(@"Data inserted ...");
        }
             sqlite3_reset(compiledStatement);
    }
        sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
[self showData];
}

then i am selecting one column from database to see whether data got inserted or not ,

-(void)showData
{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDir = [documentPaths objectAtIndex:0];

NSString *databasePath = [documentsDir stringByAppendingPathComponent:@"Database.sqlite"];

NSString *databasePathFromApp = [ [ [NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Database.sqlite"];

NSFileManager *fileManager = [NSFileManager defaultManager];

if ( ![ fileManager fileExistsAtPath:databasePathFromApp ] )

    return;

[ fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil ];

sqlite3 * database;




NSMutableArray * arry_ttl = [[NSMutableArray alloc]init];

if (sqlite3_open( [databasePath UTF8String], &database) == SQLITE_OK)
{
    NSString * insertSQL = [NSString stringWithFormat:@"SELECT N_Title FROM news_array"];

    const char *insert_stmt = [insertSQL UTF8String];
     sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database, insert_stmt,-1, &compiledStatement, NULL)==SQLITE_OK)
    {
    while (sqlite3_step(compiledStatement) == SQLITE_ROW)
    {
        NSString *title = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(compiledStatement, 1)];

        NSMutableDictionary *dic = [NSMutableDictionary new];

        [dic setObject:title forKey:@"title"];



        if(![arry_ttl containsObject:dic])
        {
            [arry_ttl addObject:dic];
           // [ary_ids addObject:id1];
        }
    }
        sqlite3_reset(compiledStatement);
 }
     sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}

i have checked the procedure at insert time , every time (10 array objects as per loop) got NSLog message when step function got succeed .

but in -(void)showdata function , at step function showing error of null string , as if data is not getting anything from database .

so here , what am i doing wrong ? am i wrong somewhere implementing the database procedure ?

and how to check externally , whether our data got inserted into database or not ? i mean if we open the updated database into sqlite manager , will it show the updated data in it ?

please , help me clear my doubts .

Moxarth
  • 303
  • 4
  • 13

1 Answers1

1

The code you posted copies an SQL file from the bundle, inserts an entry, and then copies the original SQL file from the bundle again before opening it and trying to read the newly added entry. Of course nothing has been added. You overwrote your file with the starting file that has not had anything added to it.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • ok . i am getting it what you are trying to say or problem is . so what should i do here now . i am implementing sqlite first time in real time . i have followed many tutorials but couldnt find the perfect procedure for it . which code procedure should i follow according to you ? can you guide me ? any reference ? or any link ? or any code ? anything you have . – Moxarth Nov 28 '16 at 04:45
  • as you suggested , i have changed code accordingly , – Moxarth Nov 28 '16 at 10:34
  • // Get the documents directory NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDir = [documentPaths objectAtIndex:0]; // Build the path to the database file self.databasePath = [documentsDir stringByAppendingPathComponent:@"Database.sqlite"]; – Moxarth Nov 28 '16 at 10:35
  • if (!databaseAlreadyExists) { NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *databasePathFromApp = [ [ [NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Database.sqlite"]; if ( ![ fileManager fileExistsAtPath:databasePathFromApp ] ) { NSLog(@"file does not exists at path"); return; } [ fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil ]; NSLog(@"DB created"); } – Moxarth Nov 28 '16 at 10:36
  • title is the second column . so according to that , NSString *title = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(compiledStatement, 2)]; .. but still i am getting same error at this line of code as null string . – Moxarth Nov 28 '16 at 10:40
  • i have made changes as you guided , now data are being fetched . but another issue has appeared . CURD operation is working perfectly on simulator but again , not working on device . on device also happening the same . data are being inserted but could not be fetched . – Moxarth Nov 29 '16 at 04:36
  • i had to do many code modifications and now i am getting output exactly as i wanted . but initially your advice helped me a lot to understand the fundamental mistake . thanks a lot . – Moxarth Nov 30 '16 at 04:41