Code:
#try {
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
const char * sql="Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%%%#%%'";
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [searchWord UTF8String], -1, SQLITE_TRANSIENT);
while (sqlite3_step(statement) ==SQLITE_ROW)
{
}
}
else
NSAssert1(0, #"Error in candidateinfo. '%s'", sqlite3_errmsg(database));
sqlite3_reset(statement);
}
}#catch (NSException * e) {
NSLog(#"Exception is %#, %#", [e name], [e reason]);
}#finally {
sqlite3_finalize(statement);
sqlite3_close(database);
}
I try to fetch data from sqlite based on search keyword.I tried with like statement.The query is not executing and is goes out of while loop.what is wrong with my code.thanks in advance
Try creating your Query using NSString :
NSString *sql = [NSString stringWithFormat:#"Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%#'", searchWord] ;
if (sqlite3_prepare_v2(database, [sql cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK)
{
}
Problem is that you are using 'sqlite3_bind_text' in wrong way.
Your query must be :
const char * sql="Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation like '%%?%%'";
You are missing '?'
I found answer to my question
NSString *query = [NSString stringWithFormat:#"Select Id, Name,Designation, Skill, Credits, Selected from candidate_info where Designation LIKE '%%%#%%'", searchWord];
const char *sql = [query UTF8String];
Related
I am trying to update row in a loop and its not working. I have explained the scenario below
I have got set of values from web services stored in arrays. Now i have to update those values in DB by looping through the array. Below is the code am using:
NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"db_name" ofType:#"sqlite"];
sqlite3 *database;
sqlite3 *database1;
sqlite3_open([dbPath UTF8String], &database1);
sqlite3_open([dbPath UTF8String], &database);
NSInteger loopCnt = 0;
NSString *s = [[NSString alloc] init];
const char *sql;
sqlite3_stmt *selectstmt;
NSString *q = [[NSString alloc] init];
for(NSString *itemId in itemIds)
{
s = [NSString stringWithFormat:#"SELECT * from table where id=%#", itemId];
sql = [s UTF8String];
int result = sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL);
if(result == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
if ((char *)sqlite3_column_text(selectstmt, 0) != NULL)
{
rowNumVal = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
col1 = [values1 objectAtIndex:loopCnt];
col2 = [values2 objectAtIndex:loopCnt];
if([rowNumVal integerValue] > 0)
{
q = [NSString stringWithFormat:#"UPDATE table set col1=?, col2=? WHERE id=?"];
}
}
}
}
sqlite3_finalize(selectstmt);
sqlite3_exec(database1, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
sqlite3_stmt *stmt;
const char *query = [q UTF8String];
if(sqlite3_prepare_v2(database1, query, -1, &stmt, NULL)== SQLITE_OK)
{
if(sqlite3_bind_text(stmt, 1, [col1 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 1 %s", sqlite3_errmsg(database1));
}
if(sqlite3_bind_text(stmt, 2, [col2 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 2 %s", sqlite3_errmsg(database1));
}
if (sqlite3_step(stmt) != SQLITE_DONE){
NSLog(#"Delete commit failed. Error %s", sqlite3_errmsg(database1));
}
if(sqlite3_reset(stmt)!= SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
}
sqlite3_trace(database1, sqliteCallbackFunc, NULL);
sqlite3_finalize(stmt);
if(sqlite3_exec(database1, "COMMIT TRANSACTION", 0, 0, 0) != SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
loopCnt++;
}
sqlite3_close(database);
sqlite3_close(database1);
I am fetching the values using id to check row exists and if exists am updating. Everything logs and runs fine but still DB is not getting updated.
Please let me know where is the issue.
You need to call:
sqlite3_finalize(stmt);
Before:
if(sqlite3_reset(stmt)!= SQLITE_OK)
{
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
In current code, you are resetting the prepared SQLite statement to it's initial state before finalizing it.
Another issue is, you are trying to update the database that is located in App Bundle. It won't work, because app bundle is read-only. You need to copy the database to document directory and do the operations on that copied database.
I have a "messages table" , and i want only to retrieve the "user ID" with his last message.
I tried to add "2 sql statements" inside each other , But it keeps on looping without stopping,
sqlite3_stmt *statement;
NSMutableArray * messages = [[NSMutableArray alloc]init];
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT DISTINCT FROMID , USERNAME from CHATCOMPLETE"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_chatDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
int userID = [[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)] integerValue];
NSString *querySQL2 = [NSString stringWithFormat:
#"SELECT MESSAGE , USERNAME from CHATCOMPLETE where FROMID=\"%d\"",userID];
const char *query_stmt2 = [querySQL2 UTF8String];
if (sqlite3_prepare_v2(_chatDB,
query_stmt2, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"LAST MESSAGE %#",[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)]);
sqlite3_reset(statement);
}
}
}
sqlite3_reset(statement);
}
}
return messages;
UPDATE:
This is the insert message
-(void)saveData:(NSString *)message toID:(int)toID fromID:(int)fromID isRead:(BOOL)read date:(NSDate *)date messageID:(int)messageID userName:(NSString*)userName
{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO CHATCOMPLETE (MESSAGE, TOID, FROMID, READ, date, MESSAGEID, USERNAME) VALUES (\"%#\", \"%d\", \"%d\", \"%c\", \"%#\", \"%d\", \"%#\")", message, toID, fromID, read, date,messageID,userName];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_chatDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"DONE");
/* status.text = #"Contact added";
name.text = #"";
address.text = #"";
phone.text = #"";*/
} else {
// status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_chatDB);
}
}
This is the query to get the last message with a given fromID:
SELECT * FROM chatting WHERE fromID=9999 ORDER BY id DESC LIMIT 1
In SQLite 3.7.11 or later, the following query will return the message with the largest date for each sender:
SELECT *, MAX(date)
FROM ChatComplete
GROUP BY FromID
There are a few issues:
You have only one sqlite3_stmt variable for your two nested queries. You want a separate sqlite3_stmt for each.
You are calling sqlite3_reset. That is only used when binding new values to ? placeholders in your prepared statement, which is not applicable here. Worse, you're calling it inside your loop.
Unrelated to the problem at hand, but for each prepared statement, don't forget to call sqlite3_finalize when done looping through the results, in order to release the memory used when preparing the statements.
Thus, you might want something like:
sqlite3_stmt *userStatement;
sqlite3_stmt *messageStatement;
int rc; // the return code
NSMutableArray * messages = [[NSMutableArray alloc]init];
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_chatDB) == SQLITE_OK)
{
const char *query_stmt = "SELECT DISTINCT FROMID , USERNAME from CHATCOMPLETE";
if (sqlite3_prepare_v2(_chatDB, query_stmt, -1, &userStatement, NULL) != SQLITE_OK)
{
NSLog(#"%s: prepare userStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
else
{
while ((rc = sqlite3_step(userStatement)) == SQLITE_ROW)
{
int userID = [[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)] integerValue];
const char *query_stmt2 = "SELECT MESSAGE , USERNAME from CHATCOMPLETE where FROMID=? ORDER BY timestamp DESC LIMIT 1"; // change the `ORDER BY` to use whatever field you want to sort by
if (sqlite3_prepare_v2(_chatDB, query_stmt2, -1, &messageStatement, NULL) != SQLITE_OK)
{
NSLog(#"%s: prepare messageStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
else
{
if (sqlite3_bind_int(messageStatement, 1, userID) != SQLITE_OK)
{
NSLog(#"%s: bind userID %d failed: %s", __PRETTY_FUNCTION__, userID, sqlite3_errmsg(_chatDB));
}
while ((rc = sqlite3_step(messageStatement)) == SQLITE_ROW)
{
NSLog(#"LAST MESSAGE %#",[[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)]);
}
if (rc != SQLITE_DONE)
{
NSLog(#"%s: step messageStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
sqlite3_finalize(messageStatement);
}
}
if (rc != SQLITE_DONE)
{
NSLog(#"%s: step userStatement failed: %s", __PRETTY_FUNCTION__, sqlite3_errmsg(_chatDB));
}
sqlite3_finalize(userStatement);
}
}
else
{
NSLog(#"%s: open %# failed", __PRETTY_FUNCTION__, _databasePath);
}
return messages;
Note, this code sample, in addition to my three points above, also:
Log errors using sqlite3_errmsg if sqlite3_prepare_v2 fails.
Added check on return codes from sqlite3_step, too, again logging sqlite3_errmsg if it fails.
Added log if sqlite3_open failed.
Use sqlite3_bind_int() rather building SQL using stringWithFormat. In this case, because userID is numeric, this isn't critical, but if ever using string values in your WHERE clauses, using the sqlite3_bind_text() function becomes critical, so I just wanted to show the pattern.
For example, look at your save routine and try saving a message that happens to have double quotation mark in it (e.g. I spoke with Bob and he says "hello" to you.). Your stringWithFormat construct will fail. If you use sqlite3_bind_text, it will solve that problem.
BTW, as you can see, when you add all of the proper validation of results, binding of values, etc., the code becomes a bit unwieldy. You might consider using FMDB, which greatly simplifies your SQLite Objective-C code.
Help, not working UPDATE in SQite. query is executed but the changes do not occur
const char *dbPath=[databasePath UTF8String];
if (sqlite3_open(dbPath, &contactDB)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update poi set test=\"111\"";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(contactDB, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Executed");
}
}
sqlite3_close(contactDB);
you made minor mistake....
Write ur stuff in following template, you missed the main execution statement i.e.
sqlite3_step(statement);
What is happening here, you are just preparing the statement and not executing it..
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &database_object) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"update table_name set column_name = \"%#\"", Your_value];
const char *sql_stmt = [sql UTF8String];
if(sqlite3_prepare_v2(database_object , sql_stmt, -1, &statement, NULL) != SQLITE_OK)
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(database_object));
if(SQLITE_DONE != sqlite3_step(statement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database_object));
sqlite3_finalize(statement);
}
Make these changes in your code and try, i think it will work...
You haven't executing the Query :
sqlite3_prepare_v2- Just prepared not to execute(affect) , You need to execute it
Try this Out:
const char *dbPath=[databasePath UTF8String];
if (sqlite3_open(dbPath, &contactDB)==SQLITE_OK) {
NSLog(#"database Opened");
const char* updateQuery="update poi set test=\"111\"";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(contactDB, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(#"Query Prepared to execute");
}
if(sqlite3_step(stmt) != SQLITE_DONE){
NSAssert1(0, #"Error while updating. '%s'", sqlite3_errmsg(database));
}else
NSLog(#"Executed");
sqlite3_close(contactDB);
}
I have done lot of googling on updating the created sqlite table still i did not able to update my table in my sample app .Can any one please tell me what is wrong with my below code .IT works fine till sqlite3_prepare_v2.Once it reach if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK) condition it is not going into this if() condition can any one tell what is happening here?
const char *dbpath = [[self DBPath] UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySql=[NSString stringWithFormat:#"UPDATE Table1 SET AppEndTime = %# WHERE AppID= %d",AppEndTime,appID];
const char *sql=[querySql UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK){
sqlite3_bind_int(statement, 1, sessionID);
sqlite3_bind_text(statement, 6, [sessionEndTime UTF8String], -1, SQLITE_TRANSIENT);
}
}
char* errmsg;
sqlite3_exec(database, "COMMIT", NULL, NULL, &errmsg);
if(SQLITE_DONE != sqlite3_step(statement)){
NSLog(#"Error while updating. %s", sqlite3_errmsg(database));
}
else{
sqlite3_reset(statement);
}
sqlite3_finalize(statement);
sqlite3_close(database);
Please replace you code as given below.I hope it will solve your problem.
if (sqlite3_prepare_v2(database, sql, -1, &Statement1, NULL) == SQLITE_OK) {
sqlite3_bind_text(Statement1, 1, [status UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(Statement1, 2, [messageID UTF8String], -1, NULL);
int success = sqlite3_step(Statement1);
if(success != SQLITE_ERROR)
{
// NSLog(#"Success");
}
sqlite3_finalize(Statement1);
}
Here is my code which update created table. Have a look hope it'll help you.
-(BOOL)updateMyTable{
BOOL isGood = YES;
#try {
NSString *fName = [user_dic valueForKey:#"fName"];
NSString *lName = [user_dic valueForKey:#"lName"];
NSString *email_id = [user_dic valueForKey:#"email_id"];
NSString *employee_id = [user_dic valueForKey:#"employee_id"];
fName= [fName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
lName= [lName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
email_id= [email_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
employee_id= [employee_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
// NSString *autoId = [user_dic valueForKey:#"autoId"];
NSString *sql = [NSString stringWithFormat:#"UPDATE tbl_profile SET fName = '%#', lName = '%#', email_id = '%#' ,employee_id = '%#' WHERE autoId = '%#'",fName,lName,email_id,employee_id,autoId];
[database executeUpdate:sql,nil];
if (MyDelegate.isLogging) {
NSLog(#"edit user QUERY---- >>>>%#",sql);
NSLog(#"edit user RESULT CODE ---- >>>>%d:", [database lastErrorCode]);
NSLog(#"edit user RESULT ERROR MESSAGE ---- >>>>%#",[database lastErrorMessage]);
}
}#catch (NSException *exception) {
isGood = NO;
}
#finally {
}
return isGood;
Please make sure your Sqlite file is in the documents directory,Not in project folder.
Update and insert will work if and only if the file is in the document directory
see this answer
I am trying to update my sqlite database but this code is not working for me.
Please help me to find what is wrong with this.
-(BOOL)StoreFavourite:(NSString*)fav :(int)DuaId
{
NSString* mydbpath=[self pathfinder];
const char *dbpath=[mydbpath UTF8String];
if(sqlite3_open(dbpath,&database )==SQLITE_OK)
{
NSString *query = [NSString stringWithFormat:#"UPDATE Dua SET
favourite=\'%#\' WHERE dua_id=%d ",fav,DuaId];
const char *query_statement=[query UTF8String];
if(sqlite3_prepare_v2(database, query_statement, -1, &statement, NULL)==SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_DONE)
{
return YES;
}
sqlite3_finalize(statement);
}
}
return YES;
}
Please check your "mydbpath" by putting NSLog.I think you have given incorrect path.
Also try to use:
NSString *query = [NSString stringWithFormat:#"UPDATE Dua SET favourite='%#' WHERE dua_id=%d ",fav,DuaId];
here are some reason for due to which the sqlite3_prepare_v2 != SQLITE_OK :
1.The table may not present into the database.
2.Wrong query statement .
3.Wrong column name into the query statement.
You can find the exact problem using error statement by putting following in else:
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database))
please try in following manner
-(BOOL)StoreFavourite:(NSString*)fav :(int)DuaId
{
sqlite3_stmt *statement=nil;
NSString *mydbpath=[self pathfinder];
NSString *query;
if(sqlite3_open([mydbpath UTF8String],&database) == SQLITE_OK)
{
query = [NSString stringWithFormat: #"update Dua set favourite=? where dua_id=?"];
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL)
== SQLITE_OK)
{
sqlite3_bind_int(statement, 2, DuaId);
sqlite3_bind_text(statement, 1, [fav UTF8String], -1, SQLITE_TRANSIENT);
if(sqlite3_step(statement))
{
return YES;
}
else
{
return NO;
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}