Sqlite Prepare Statement - iphone

I have 12 columns in my table. In which last two columns are added newly. I use sqlite3 database. Database is created and query is executed correctly if I use where clause for any other columns other than lastly created two new columns. The last two columns return NULL string which makes the app crash throwing Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' *+[NSString stringWithUTF8String:]: NULL cString'**
When the query is executed in SQL Manager I could retrieve last two columns. I suppose somewhere something is wrong in my prepare statement.
NSString *query = #"select * from tableName where lastColumn = 'Value'";
const char *sqlStatement = [query UTF8String];
sqlite3_stmt *compiledStatement;
NSLog(#"could not prepare statement: %s\n", sqlite3_errmsg(database));
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
}
Please Help me on this. I totally have no clue where the last two columns have gone.. :)

You're passing NULL to stringWithUTF8String: method, which is not allowed. You should check the value you get from sqlite before instantiating NSString object.
const char *ctext = sqlite3_column_text(compiledStatement, 2);
if (ctext) {
text = [NSString stringWithUTF8String:ctext];
}
When you added new columns, values for this columns in all existing rows were set to NULL.

Related

SQLite- how to insert data in ios

i tried some sqlite program for practice when i insert the record with this code it give some error
-(void) insertRecordIntoTableNamed:(NSString *) tableName
withField1:(NSString *) field1
field1Value:(NSString *) field1Value
andField2:(NSString *) field2
field2Value:(NSString *) field2Value {
NSString *sql = [NSString stringWithFormat:
#"INSERT INTO ‘%#‘ (‘%#‘, ‘%#‘) VALUES (‘%#‘,’%#‘)",tableName, field1, field2, field1Value, field2Value];
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, #"Error updating table.");
}
}
the error message is
** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error updating table.'
i try to insert data through terminal and the data is retrived properly
so Please help me for inserting data through programms
may it works better when you use a char * as sql statement as an NSString object. For example:
char *sql = "INSERT INTO ‘?‘ (‘?‘, ‘?‘) VALUES (‘?‘ ....";
to replace the ? with your NSString arguments use the function below.
sqlite3_bind_text(insert_statement, 1, [tableName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 2, [field1 UTF8String], -1, SQLITE_TRANSIENT);
etc....
First you have to define the insert_statement.
static sqlite3_stmt *insert_statement = nil;
... and at the end you should reset the statement with sqlite3_reset(insert_statement);
LEFT SINGLE QUOTATION MARK is unsuitable for quoting either identifiers or values in SQLite. Quote identifiers with " (\x22) and data with ' (\x27).
Also, I hope your program is simple enough that potential SQL injection doesn't matter.

Table still exists after DROP TABLE

My iPhone application has a code like this to delete a table and re-create it.
const char *sql = [#"DROP TABLE mytable" cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_step(statement);
NSLog(#"dropped.");
} else {
NSLog(#"error. %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
// ...
// DO SQL LIKE `CREATE TABLE mytable` here.
In most cases, this code works.
But error reports say, the table still exist after the first SQL (DROP TABLE mutable) ran without an error in some rare cases. And I have never experienced that case on my devices.
Has anyone experienced this? or any information?

Objective-C Issue with deleting data from SQLITE database - result code 5

I am experiencing issues with deleting a row / data record from an SQLite database located on the iPhone. I followed advice given in the following post, but the result code from SQLite is 5. From the SQLite reference manual, 5 means:
SQLITE_BUSY 5 /* The database file is locked */
Has anyone else come across this problem or have any ideas why this would be the case?
Here is an excerpt of my code (dbrc is set to 5):
NSString *retrievedContactID = [archivedContact objectForKey:#"contact_id"];
sqlite3 *database = [FollowUPAppDelegate checkAndCreateDatabase];
NSString *deleteSQL = [NSString stringWithFormat:#"DELETE FROM Contacts WHERE contact_id = %#", retrievedContactID];
const char *delete_stmt = [deleteSQL UTF8String];
sqlite3_stmt *compiledStatement;
int dbrc; //database return code
dbrc = sqlite3_prepare_v2(database, delete_stmt, -1, &compiledStatement, NULL);
dbrc = sqlite3_step(compiledStatement);
sqlite3_finalize(compiledStatement);
compiledStatement = NULL;
if (dbrc != 101) { //anything except 101 (SQLITE_DONE for delete, *not* SQLITE_OK)
NSLog(#"Error deleting contact from database: result code %i", dbrc);
return;
}
else {
NSLog(#"deleted the customer from datasets");
}
sqlite3_close(database);
This means. your database is being used by some other process. you have to stop the other process and proceed.
I can give you an example. when you are accessing a database from your app and if you try to change the content using some external sqlite manager you would get this busy error. The solution to this problem is,stop your app and try.
You problem is similar. Your database is locked by some other process.

data is not being inserted from this insert query

I am using this code to insert the data in my database
but it is not working..
My data is not being inserted in the table ..
what can be the problem??
in function.h
+(BOOL)insertStudentinfoData:(NSString *)first_name last_name:(NSString *)last_name phone_num:(NSString *)phone_num;
in function.m
+(BOOL)insertStudentinfoData:(NSString *)first_name last_name:(NSString *)last_name phone_num:(NSString *)phone_num
{
NSString *sql = [NSString stringWithFormat:#"insert into add_data
values(NULL,'%#','%#','%#')",first_name,last_name,phone_num];
return [DBOperation executeSQL:sql];
}
And I am giving the data from this
[Function insertStudentinfoData:#"hello" last_name:#"w3qrq" phone_num:#"efew"];
but my data is not being inserted in the table
////In DBOperation.h
+(BOOL) executeSQL:(NSString *)sqlTmp {
if(conn == SQLITE_OK) {
NSLog(#"\n\n%#",sqlTmp);
const char *sqlStmt = [sqlTmp cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *cmp_sqlStmt1;
int returnValue = sqlite3_prepare_v2(database, sqlStmt, -1, &cmp_sqlStmt1, NULL);
returnValue == SQLITE_OK ? NSLog(#"\n Inserted \n") :NSLog(#"\n Not Inserted \n");
sqlite3_step(cmp_sqlStmt1);
sqlite3_finalize(cmp_sqlStmt1);
if (returnValue == SQLITE_OK) {
return TRUE;
}
}
return FALSE;
}
I guess you are passing the NULL value for PRIMARY KEY, first reset the simulator
if you are not specifying the column name and inserting the values then you should pass the value for each column in particular order of column created otherwise its a good idea to specify column
NSString *sql = [NSString stringWithFormat:#"INSERT INTO add_data
(first_name,last_name,phone_num) VALUE('%#','%#','%#')",first_name,last_name,phone_num];
or
NSString *sql =[NSString stringWithFormat:#"INSERT INTO add_data
(first_name,last_name,phone_num,email,address,city,zip) VALUES
('%#','%#','%#','%#','%#','%#','%#');",first_name,last_name,phone_num,email,addr‌​ess,city,zip];
are you sure that the database is initialized correctly? I always had trouble with the DB not actually there. Which DB Framework are you using?
[EDIT] do you see this log statement?
NSLog(#"\n\n%#",sqlTmp);
Did you write the DBOperations class yourself? I think there is some issue there with the static variable you're using. I'd suggest to either use an existing db framework like fmdb or something, or else modify your class so that it uses the Singleton Pattern.
Oh, and one thing: Are you calling all methods from the same thread? SQlite DBs are not thread safe!
[edit2] You can use the link provided here: SQLite3 error - iOS to check what the value in returnValue actually states - and then figure out the underlying error.
It's probably best for now to modify your not inserted statement like this:
returnValue == SQLITE_OK ? NSLog(#"\n Inserted \n") :NSLog(#"\n Not Inserted with code: %i\n",returnValue);
What if you provide the names of the columns to be inserted:
insert into T (foo, bar, baz)
values( ....)
Try it this way to see full error code and message:
The sql comes as NSString *, do not convert it into a cstring.
int rc;
sqlite3_stmt *sel;
if ((rc = sqlite3_prepare_v2(db_handle, [sql UTF8String], -1, &sel, NULL)) != SQLITE_OK) {
NSLog(#"cannot prepare '%#': %d (%s)", sql, rc, sqlite3_errmsg(db_handle));
return;
}
if (sqlite3_step(sel) != SQLITE_DONE) {
NSLog(#"error insert/update: '%s'", sqlite3_errmsg(db_handle));
...

SQLite database - cannot see updates

I have a sqlite database and I am adding to it new words. The problem is that I can see them added to a table only after restarting application. The "SELECT" statement doesn't "see" newly added elements before restarting application.
Why may this happen?
I am creating some kind of a dictionary. Here is how I add new items:
const char *sql_query = "INSERT INTO words(word) VALUES(?)";
if(sqlite3_prepare_v2(database, sql_query, -1, &addWordsStmt, NULL) != SQLITE_OK)
{
return FALSE;
}
sqlite3_bind_text(addWordsStmt, 1, [ word UTF8String], -1, SQLITE_TRANSIENT);
if( sqlite3_step(addWordsStmt) != SQLITE_DONE)
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
sqlite3_reset(addWordsStmt);
sqlite3_finalize(addWordsStmt);
And here is my retrieval code:
const char *sql_query = "SELECT word FROM words WHERE id=?";
if(sqlite3_prepare_v2(database, sql_query, -1, &getWordsStmt, NULL) != SQLITE_OK)
{
return;
}
sqlite3_bind_int(getWordsStmt, 1, wordid);
if( sqlite3_step(getWordsStmt) != SQLITE_ROW)
{
NSLog(#"Error while getting data. '%s'", sqlite3_errmsg(database));
sqlite3_reset(getWordsStmt);
return;
}
NSString *word = [NSString stringWithUTF8String:(char *)sqlite3_column_text(getWordsStmt, 0)];
sqlite3_reset(getWordsStmt);
sqlite3_finalize(getWordsStmt);
My guess is that you are in a transaction. There must be some other calls during your open and close routines that are wrapping your calls in a transaction and not displayed in your code fragments.
That is why you don't see the new words until you application exits
There's your problem:
const char *sql_query = "SELECT word FROM words WHERE id=?";
This isn't how you use SQL. Instead, you should be using SELECT word FROM words; and stepping to get each row as long as you're getting SQLITE_ROW until you get SQLITE_DONE. That will get you all your words. How are you going to find a word by id when you don't know the id of newly added words?