SQLite select statement returns empty array - sqlite

I am trying to fetch data from SQLite database(NSArray of strings) and populate the contents in table view cells. I tried to execute the query in command prompt and it works fine. But in code, it returns an empty array.
NSString *temp = [[NSString alloc]initWithFormat:#"select img.image from images img,illness i,illness_images ii where img.img_id=ii.img_id and i.i_id=ii.i_id and i.i_id = '%d'",illid];
const char *sqlStatement = [temp UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Loop through the results and add them to the array
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Read the data from the result row
NSString *imgname = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
[imglist addObject:imgname];
sqlite3_finalize(compiledStatement);
}
}
else{
NSAssert1(0,#"Error retrieving image names '%s'",sqlite3_errmsg(database));
}
I tried to debug and when it reaches while(sqlite3_step(compiledStatement) == SQLITE_ROW) , it does not enter the loop.
Not sure whats the mistake I am doing.
Thanks!

Try NSLog after assigning the string query to temp variable.
and check if the variable illid is giving you the correct value and run that query on the database directly.
NSString *temp = [NSString stringWithFormat:#"select img.image from images img,illness i,illness_images ii where img.img_id=ii.img_id and i.i_id=ii.i_id and i.i_id = %d",illid];
and you better release the allocated object or use class methods setting value, for memory management.
HTH.

Related

Writing Image to SQLite Database always fails

I am attempting to write a png to a SQLite3 database in C#. I have managed to correctly import the external DLL function sqlite3_bind_blob thanks to the answer here. But now I am getting an error when I write the image to my SQLite3 database.
Can you tell me what I am doing wrong? The function function sqlite3_bind_blob is returning the error 21 - SQLITE_MISMATCH 20 - Data type mismatch. I am unsure what exactly is going wrong.
Heres my code:
string query = string.Format("INSERT OR REPLACE INTO myTable(lat, lon, image) VALUES({0}, {1}, ?1);", lat, lon);
if (sqlite3_prepare_v2 (_connection, query, query.Length, out stmHandle, IntPtr.Zero) != SQLITE_OK) {
IntPtr errorMsg = sqlite3_errmsg (_connection);
throw new SqliteException (Marshal.PtrToStringAnsi (errorMsg));
}
IntPtr SQLITE_TRANSIENT = new IntPtr(-1); // Represents SQLITE_TRANSIENT
int res = sqlite3_bind_blob (stmHandle, 1, blob, blob.Length, SQLITE_TRANSIENT);
// res always equals 21
From my debugging I know that the blob correctly contains valid png data because I can write it out to a file and open that file. I also know that the length of the blob is correct aswell. Maybe its my query string INSERT OR REPLACE INTO myTable(lat, lon, image) VALUES({0}, {1}, ?1);?
You are mixing managed with unmanaged code.
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
You are providing managed IntPtr blob instead of unmanaged const void*blob.
You should be very sure about what you're doing when mixing managed with unmanaged code - and it seam you're not...
You may workaround this situation something like this (I don't have compiler right now) using:
unsafe { //this is for C#... probably not needed in C++/CLI
int res = sqlite3_bind_blob (stmHandle, 1, (const void*) blob.ToPointer(), (int) blob.Length, SQLITE_TRANSIENT);
}
Anyways, unless you're pretty sure you need this stuff, I recommend you to go on managed system.data.sqlite and abandon SQLite3 CAPI.

If new is a pointer, that stores the hexadecimal address of the new node, why does new still refer to the node?

If new is a pointer, that stores the hexadecimal address of the new node, why shouldn't it be *new->n=n or *new.n=n instead of new->n=n? Wouldn't *new refer to the actual node?
//insert new node
void insert(int n)
{
// create new node
node* new = malloc(sizeof(node));
// check for NULL
if (new == NULL)
{
exit(1);
}
// initialize new node
new->n = n;
new->next = NULL;
// insert new node at head
new->next = head;
head = new;
}
When you use -> notation, that automatically dereferences new so that you're dealing with the actual variable, not the pointer.
Btw, please don't use new as a variable name :)
new.n is an address.
To change the value of it you need to de-reference it. This can be done like:
*(new.n) or new->n
The reason for this is because the * operator has a very high order of importance in the order of operations. Also you aren't mallocing correct. You need to malloc the sizeof(struct node). You are only allocating the size of a pointer which is either 4 or 8 bytes depending on your architecture.

Setting a text = a string crashes my program

I am new at this so be gentle.
I have this function:
- (void) Morepoint {
gscore ++;
scoreString = [NSString stringWithFormat:#"%i", gscore];
lblscore.text = scoreString;
}
Where gscore is a global. scoreString is a NSString and lblscore is a label.
Every time I insert the function in my gameloop, the program stops to run.
Can anyone figure that out?
If I call the function from outside my gameloop, everything works fine, why?
You own the object returned from initWithFormat which you are responsible for releasing, but you don't own the object returned from stringWithFormat which returns an autoreleased string and so do not need to release it (if you do want to have ownership of it, you must retain it).
So for resolving your issue try to assign your value like this,
- (void) Morepoint
{
gscore ++;
scoreString = [[NSString alloc] initWithFormat:#"%i",gscore];
lblscore.text = scoreString;
}
Hope this helps you. Just Give it a try :)

NSString stringWithUTF8String return null on device, but ok on simulator

I have a really weird problem. Basically just convert a char to nsstring and store them in an nsmutable array.
But the code runs ok on simulator, but crash on device.
Here is the crash code,
char t = 'A' + i;
NSString* alphabetString = [NSString stringWithUTF8String:&t]; //substringToIndex:1];
[tempArray addObject:alphabetString];
Basically the stringWithUTF8String will return NULL on device, but return valid value on simulator.
The device is an iPhone 4s.
I did not see any notification of changes on NSString stringwithutf8string on iOS5 release.
Thanks.
The address of a single char is not a C-style string. You need to ensure it's null terminated with something like:
char t = 'A' + i;
char s[2]; s[0] = t; s[1] = '\0';
NSString* alphabetString = [NSString stringWithUTF8String:s];
From the docpage:
Parameters
bytes : A NULL-terminated C array of bytes in UTF8 encoding.
You can't pass the address of a single char value to -stringWithUTF8String. That function is expecting a null-terminated string, and you're not passing it one. This results in undefined behavior: anything at all could happen. It might appear to succeed, it might fail benignly, or it might erase your file system. But more likely, it will just crash your program.
You should create a two-character array that's null-terminated instead:
char t[2] = {'A' + i, 0}; // Two-character null-terminated array
NSString* alphabetString = [NSString stringWithUTF8String:t];
Alternatively, you can also use -stringWithFormat: with the %c format specifier to get a string containing a single character:
NSString* alphabetString = [NSString stringWithFormat:#"%c", 'A' + i];

sqlite3 - while loop is not executed

Strange Problem anyone please solve it
While loop is not executing, in my read database code.
Here is my code
NSString * query=#"select usernote from savenote where recipename like ? ";
const char * sqlStatement=[query UTF8String];
sqlite3_stmt *compiledStatement;
sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
if (sqlite3_prepare_v2 (database, sqlStatement,-1,&compiledStatement,NULL)==SQLITE_OK)
{
sqlite3_bind_text(compiledStatement,1,[selString UTF8String],-1,SQLITE_STATIC);
NSLog(#"selected:%#",selString);
while (sqlite3_step(compiledStatement)== SQLITE_ROW)
{
NSString * notz=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement,0)];
[Notes addObject:notz];
NSLog(#"n:%#",Notes);
txt.text=[Notes objectAtIndex:0];
}
}
}
In the above code all works fine except the while loop is never being executed.
Thanks for reading my post.
I guess the problem is in the query. Add single-quotes(') in the like clause.
"select usernote from savenote where recipename like '?'";
You can follow this link
In your case Code will look like,
const char * sqlStatement = "select usernote from savenote where recipename like ?001 ";
sqlite3_bind_text(compiledStatement,1,[selString UTF8String],-1,SQLITE_TRANSIENT);

Resources