I try to retrieve data from sqlite. Unfortunately the table is filled with null values.
The console shows FIRST ID RECUPERÉ : (null). Can you give me your opinions please?
This is the code:
NSString * statementID = [NSString stringWithFormat:#"SELECT id_message FROM messages;"];
const char * sql_stmt_id = [statementID UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(contactDB, sql_stmt_id, -1, &compiledStatement, NULL) == SQLITE_OK)
{
[tableauMsgReceived removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
[tableauMsgReceived addObject:[NSString stringWithFormat:#"%s",(char *) sqlite3_column_text(compiledStatement, 0)]];
NSLog(#"First ID : %#", [tableauMsgReceived objectAtIndex:0]);
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(contactDB);
The only way that the NSLog statement will give that result given your code is if tableauMsgReceived is nil.
Somewhere you need to do:
tableauMsgReceived = [[NSMutableArray alloc] init];
First of all, make sure you have done something like
tableauMsgReceived = [[NSMutableArray alloc] init];
Then, check whether database opened successfully
if (sqlite3_open([YourDBPath UTF8String], &yourDatabase) == SQLITE_OK){}
Last thing, maybe you can try
[tableauMsgReceived addObject:[NSString stringWithUTF8String:(const char *)sqlite3_column_text(statement, 0)]];
Related
I am trying to retrieve some data from my sqlite table base on a date, but I am getting EXC_BAD_ACCESS(code=EXC_1386_GPFLT) error. Here is my method to fetch data-
-(NSMutableArray*)fetchDataFromTable:(NSString*)tableName whenDate:(NSString*)activeDate{
NSMutableArray *resultArray=[[NSMutableArray alloc]init];
NSString *query = [NSString stringWithFormat:#"select * from %# where ActiveDate = \"%#\"", tableName, activeDate];
if ([self canOpenDatabase]) { //checks if database can be openned
sqlite3_stmt *statement=nil;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW){
NSMutableArray *fetchedResults=[[NSMutableArray alloc]init];
int numberOfColumns = sqlite3_column_count(statement);
for (int i=0; i< numberOfColumns; i++){
char *dataAsChars = (char *)sqlite3_column_text(statement, i);
if (dataAsChars != NULL) {
NSString *dataString = [[NSString alloc] initWithUTF8String:dataAsChars];
[fetchedResults addObject:dataString];
}
}
[resultArray addObject:fetchedResults];
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
else{
NSLog(#"Data can not be retrived");
}
return resultArray;
}
else{
return resultArray;
}
}
I also trying printing the query. It shows
select * from Time_table where ActiveDate = "2016-01-01"
Please Help me out.
There are several issues.
Pair the call to sqlite3_close with the success of opening the database.
Pair the call to sqlite_finalize with the success of preparing the statement.
Don't close the database or finalize the statement inside the loop.
Don't build queries using stringWithFormat. Properly bind values into the prepared statement.
The issue was very obvious yet very intuitive. I am glad that I faced this issue. At least I won't do it again. So, here is the simple fix and the reason behind it-
In case of database object fetching, EXC_BAD_ACCESS normally happens when -
An object is not initialised or
An object is already released untimely
So, in case, I were never to use the prepared statement or completely done working with the statement, I should use sqlite_finalize. In may method, I used the statement after I finalised the statement.
So the easy fix was to finalise after the while statement-
-(NSMutableArray*)fetchDataFromTable:(NSString*)tableName whenDate:(NSString*)activeDate{
NSMutableArray *resultArray=[[NSMutableArray alloc]init];
NSString *query = [NSString stringWithFormat:#"select * from %# where ActiveDate = \"%#\"", tableName, activeDate];
if ([self canOpenDatabase]) {
sqlite3_stmt *statement=nil;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW){
NSMutableArray *fetchedResults=[[NSMutableArray alloc]init];
int numberOfColumns = sqlite3_column_count(statement);
for (int i=0; i< numberOfColumns; i++){
char *dataAsChars = (char *)sqlite3_column_text(statement, i);
if (dataAsChars != NULL) {
NSString *dataString = [[NSString alloc] initWithUTF8String:dataAsChars];
[fetchedResults addObject:dataString];
}
}
[resultArray addObject: fetchedResults];
}
sqlite3_finalize(statement);
}
else{
NSLog(#"Data can not be retrived");
}
sqlite3_close(database);
return resultArray;
}
else{
return resultArray;
}
}
Hi can anyone point out what I'm doing wrong please? The error is this:
SQL error 'out of memory' (7)
- (NSArray *)RecipeInfo
{
NSMutableArray *retval = [[NSMutableArray alloc] init];
NSString *query = [NSString stringWithFormat:#"SELECT key, name FROM recipes WHERE type = \'%#\'", self.RecipeType];
NSLog(query);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK)
{
NSLog(#"[SQLITE] Error when preparing query!");
NSLog(#"%s SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(_database), sqlite3_errcode(_database));
}
else
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
int uniqueId = sqlite3_column_int(statement, 0);
char *nameChars = (char *) sqlite3_column_text(statement, 1);
NSString *name = [[NSString alloc] initWithUTF8String:nameChars];
RecipeInfo *info = [[RecipeInfo alloc] initWithUniqueId:uniqueId name:name];
[retval addObject:info];
}
sqlite3_finalize(statement);
}
return retval;
}
The sql executes fine in the database management environment I use, it has to be something to do with the way I'm using the sql api, can anyone spot whats wrong?
You can get that error, confusingly, if you neglected to open the database and the pointer is NULL (or, as rmaddy says, if it's NULL for any reason). Put a log statement where you open the database and make sure that it was successful and that you have a valid sqlite3 pointer.
I have SQLite database with 5 columns named: Name, ID, ChildID, ParentID, BrotherID.
In this database I have many records and I want to store one of all columns value in array and return this array. For example I want to get all value in ParentID column. I use this query code:
Select ParentID from Table1 (Table1 is name of table)
This is my code for get array from certain column :
/*==================================================================
METHOD FOR GETTING MIDIFIED FROM DATABASE
==================================================================*/
- (NSMutableArray*)readingModified
{
ModiArray = [[NSMutableArray alloc] init];
// Setup the database object
sqlite3 *database2;
// Open the database from the users filessytem
if(sqlite3_open([[self DatabaseSqlite] UTF8String], &database2) == SQLITE_OK)
{
// Setup the SQL Statement and compile it for faster access
//SQLIte Statement
NSString *sqlStatement_userInfo =[NSString stringWithFormat:#"Select ParentID from Table1"];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database2, [sqlStatement_userInfo UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Init the Data Dictionary
NSMutableDictionary *_dataDictionary2=[[NSMutableDictionary alloc] init];
NSString *_recordParentID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
[_dataDictionary2 setObject:[NSString stringWithFormat:#"%#",_recordModified] forKey:#"ParentID"];
[array addObject:_dataDictionary2];
}
}
else
{
NSLog(#"No Data Found");
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database2);
return ModiArray;
}
please tell me my mistake.
my friend a few be careful.
this code is right but in line you mistake :
[array addObject:_dataDictionary2];
instead array put ModiArray
/*==================================================================
METHOD FOR GETTING MIDIFIED FROM DATABASE
==================================================================*/
- (NSMutableArray*)readingModified
{
ModiArray = [[NSMutableArray alloc] init];
// Setup the database object
sqlite3 *database2;
// Open the database from the users filessytem
if(sqlite3_open([[self DatabaseSqlite] UTF8String], &database2) == SQLITE_OK)
{
// Setup the SQL Statement and compile it for faster access
//SQLIte Statement
NSString *sqlStatement_userInfo =[NSString stringWithFormat:#"Select ParentID from Table1"];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database2, [sqlStatement_userInfo UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Init the Data Dictionary
NSMutableDictionary *_dataDictionary2=[[NSMutableDictionary alloc] init];
NSString *_recordParentID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
[_dataDictionary2 setObject:[NSString stringWithFormat:#"%#",_recordModified] forKey:#"ParentID"];
[ModiArray addObject:_dataDictionary2];
}
}
else
{
NSLog(#"No Data Found");
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database2);
return ModiArray;
}
You are adding object to array and allocating and returning ModiArray.
I have tried following the guide on this page SQLite Tutorial? Deleting Data | iPhone SDK Articles but I just can't understand how to implement it in my app, because I the NSMutableArray isn't declared in the AppDelegate as it is in the tutorial
Can someone have a look and guide me through it? I want to be able to delete rows from the tableview and the database and to be able to add data as well.
Here is my app: http://ge.tt/9JNVd89?c
Even the slightest tip will be appreciated.
Will probably need a bit more information as to your current level of knowledge. How far have you gotten? Are you able to connect and read data from it? Do you understand how SQL works?
If you wanted to retrieve data from the db you could write something like the following:
+ (NSArray *)getAllUsers
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSMutableArray *userArray = [NSMutableArray array];
NSString *fullQuery = #"SELECT * FROM User";
const char *sql = [fullQuery UTF8String];
if(sqlite3_prepare_v2(db, sql, -1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0, #"Error preparing statement '%s'", sqlite3_errmsg(db));
else
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
User *currentUser = [[User alloc] init];
[User setPk:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)]];
[User setName:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)]];
[User setAge:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)]];
[userArray currentUser];
[currentUser release];
}
}
sqlite3_finalize(statement);
sqlite3_close(db);
return [NSArray arrayWithArray:userArray];
}
and if you wanted to insert data into it:
+ (void)insertUser:(NSString *)username
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSString *fullQuery = [NSString stringWithFormat:#"INSERT INTO User (userName) VALUES (%#);", username];
const char *sql = [fullQuery UTF8String];
sqlite3_prepare_v2(db, sql2, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"User inserted");
}
sqlite3_finalise(statement);
sqlite3_close(db);
}
If you are having trouble getting a database into your application and connecting to it, let me know and I can post some of that code as well.
Hope that helps :)
hi all
i have some problem in using sqlite in IOS. i have select data from database, and then i want to save that data in a variable. But when i use while(sqlite3_step(statement) == SQLITE_ROW) loop, the code never execute.
here is my code :
-(void)retrieveProjectNameFromDb:(NSString *)segmenId{
NSString *query;
NSString *nameProjectStr;
NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"database" ofType:#"sqlite"];
if (sqlite3_open([dbPath UTF8String], &db) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, #"Database failed to open.");
}else {
query = [NSString stringWithFormat:#"SELECT remote_projectname, remote_base_uri FROM REMOTE_SETTING WHERE remote_settingid = '%#' ORDER BY remote_projectname", segmenId];
NSLog(#"query : %#", query);
}
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil)==SQLITE_OK){
NSLog(#"sqlite row : %d", SQLITE_ROW);
NSLog(#"sqlite 3 : %d", sqlite3_step(statement));
while (sqlite3_step(statement) == SQLITE_ROW) {
char *nameProject = (char *)sqlite3_column_text(statement, 0);
if (nameProject == nil) {
NSLog(#"UNNAMED");
}else {
NSLog(#"else");
nameProjectStr = [NSString stringWithUTF8String:nameProject];
}
projectName.text = nameProjectStr;
nameProject = nil;
}
NSLog(#"project name : %#", projectName.text);
sqlite3_close(db);
}
}
when i nslog the value, sqlite3_step(statement) always show 101 and sqlite_row always show 100. Why it can happen??
can somebody help me, please?
thank you
Regards
-risma-
As you mentioned sqlite3_step(statement) always show 101 which means sqlite3_step has finished executions hence it means your sql query is not returning any rows from database. I would recommend you to first check in database if any record exists in table REMOTE_SETTING for remote_settingid which you are referring.
For your reference I took following constant snippet from sqlite.org
#define SQLITE_DONE 101 /* sqlite_step() has finished executing */
Remove the NSLog entry in which you are having sqlite3_step(). Since you have your NSLog statement executing sqlite3_step(), the record is already stepped through here. Hence, your while loop won't execute as there are no more rows to step through.
I think this will surely help you. :)
From your description of the logging output I would guess that your query is returning an empty row set. However I can see two other problems here:
You discard the result of your first call to sqlite3_step, because you log it then immediately call sqlite3_step again. That means you will miss the first row.
You probably should not be closing the database after a single query. You should finalize the statement after the query, but only close the database when your app shuts down.
Try:
if(sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil)==SQLITE_OK){
NSLog(#"sqlite row : %d", SQLITE_ROW);
int stepResult = sqlite3_step(statement);
NSLog(#"sqlite 3 : %d", stepResult);
while (stepResult == SQLITE_ROW) {
char *nameProject = (char *)sqlite3_column_text(statement, 0);
if (nameProject == nil) {
NSLog(#"UNNAMED");
}else {
NSLog(#"else");
nameProjectStr = [NSString stringWithUTF8String:nameProject];
}
projectName.text = nameProjectStr;
nameProject = nil;
stepResult = sqlite3_step(statement);
}
NSLog(#"project name : %#", projectName.text);
sqlite3_finalize(&statement);
}
Try with something like this..
sqlite3 *database1;
NSString *sqlStatement1 = #"";
if(sqlite3_open([databasePath UTF8String], &database1) == SQLITE_OK)
{
sqlStatement1 = [NSString stringWithString:#"SELECT uniqueid from shortlisted"];
sqlite3_stmt *compiledStatement1;
if(sqlite3_prepare_v2(database1, [sqlStatement1 cStringUsingEncoding:NSUTF8StringEncoding], -1, &compiledStatement1, NULL) == SQLITE_OK)
{
while(sqlite3_step(compiledStatement1) == SQLITE_ROW)
{
NSString * str = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
}
}
sqlite3_finalize(compiledStatement1);
sqlite3_close(database1);
}
Also close database instance whenever you open them.. if you are not closing an instance then that can cause issues..
Sorry I am pasting this from my project.. but actually I am in a bit hurry... I'll modify this answer when I reach home...