I've used the following method in my app,
-(int) getMax:(NSString *)subItemName second :(int) tableID
{
int count1=0;
sqlite3_stmt *statement;
NSString *query = [NSString stringWithFormat:#"Select MAX(NoOfItems) from billTable where SubItemName='%#' AND TableID='%d'",subItemName,tableID];
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil)== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
count1 = [[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 0)]intValue];
}
sqlite3_step (statement);
}
return count1;
}
As you can see that the my query will return the no of rows (an integer), suppose if my query returns a NULL value(if there is no such exists for the where clause condition in my database it returns NULL value. How to check it returns NULL after the query has been executed?
You can call sqlite3_column_type() to find out what type a column value has:
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil)== SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_ROW) {
if (sqlite3_column_type(statement, 0) == SQLITE_NULL)
count1 = -1; // or whatever
else
count1 = sqlite3_column_int(statement, 0);
}
sqlite3_finalize(statement);
}
Related
I have a sqlite db and i want to insert row in it . I used this code for inserting rows and make a query.
-(void)InsertRecords{
querySQL1 = #"select category from notes where id=5";
const char * query_stmt = [querySQL1 UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO notes (id, title, content,dataAdd,category) VALUES (\"%#\", \"%#\", \"%#\" ,\"%#\",\"%#\")",
#"5",
#"georgiana",
#"20",
#"12.09.2019",
#"public"];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_stmt *updateStmt = nil;
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if(sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"data inserted");
}
else{
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
}
}
else
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
querySQL1 = #"select id from notes where category LIKE 'public'";
query_stmt = [querySQL1 UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
NSString *idNr=#"";
while (sqlite3_step(statement) == SQLITE_ROW)
{
idNr =[NSString stringWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
NSLog(#"%#",idNr);
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
Everything is ok, but when I open the app again, I don't find any value for idNr.
Any useful help will be appreciated.
The NSString allocation is wrong statement, There is no need to alloc NSString object here.
The method stringWithUTF8String: is class method. This will do the allocation for NSString.
Replace your code like below:
NSString *idNr = #"";
while (sqlite3_step(statement) == SQLITE_ROW) {
idNr = [NSString stringWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
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 am trying to create loop for reading from sqlite DB, but the column count always return zero. columns=0
sqlite3_stmt *statement;
NSString *querySQL = #"SELECT * FROM Animations";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(localDB,query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
int columns = sqlite3_data_count(statement);
NSLog(#"Columns: %d",columns);
while(sqlite3_step(statement) == SQLITE_ROW)
{
for (int i=1;i<columns;i++)
{
NSString *st0 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, i)];
NSLog(#"%#",st0);
}
}
}
else
{
NSLog(#"%s","Error on SQLITE_OK");
}
https://www.sqlite.org/c3ref/data_count.html
The sqlite3_data_count(P) routine returns 0 if the previous call to sqlite3_step(P) returned SQLITE_DONE.
Try putting the data count after your sqlit3_step statement (inside your while loop)
Currently, I write query for update data in iOS
NSString *query = [NSString stringWithFormat: #"update *from ericsson_review_form_field_table set value = %# where fieldId = %# and form_index = %d",strFValue,strFieldId,formIndex];
But it is not working.
Please tell me the sql query for update value.
Here you made a mistake in writing query to update any record, just try it
NSString *updateSQL = [NSString stringWithFormat:#"UPDATE EMPLOYEES set name = '%#', department = '%#', age = '%#' WHERE id = ?",
employee.name,
employee.department,
[NSString stringWithFormat:#"%d", employee.age]];
First Google and then ask..See below example for update
UPDATE table_name
SET column1 = value1
WHERE [condition];
UPDATE CUSTOMERS
SET ADDRESS = 'Pune', SALARY = 1000.00;
NSString *updateSQL = [NSString stringWithFormat:#"update table_name SET name='%#' where regno='1000'"];
Hope it helps you....
Simple way to update record in table is as bellow
UPDATE table2
SET table2.col1 = table1.col1,
table2.col2 = table1.col2,
...
FROM table1, table2
WHERE table1.memberid = table2.memberid
Currently my code is
- (BOOL)updateReviewFields:(NSString *)strFieldId andFormIndex:(int)formIndex withFValue:(NSString *)strFValue{
sqlite3_stmt *statement = nil;
NSString *query;
if(sqlite3_open([[appDelegate databasePath] UTF8String],&database) == SQLITE_OK){
query = [NSString stringWithFormat: #"update ericsson_review_form_field_table set value = %# where fieldId = %# and form_index = %d",strFValue,strFieldId,formIndex];
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL)
== SQLITE_OK){
sqlite3_bind_text(statement, 1, [strFieldId UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 13, [strFValue UTF8String], -1, SQLITE_TRANSIENT);
if(sqlite3_step(statement))
return YES;
else
return NO;
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}
and now it is working fine.
You posted a code sample:
- (BOOL)updateReviewFields:(NSString *)strFieldId andFormIndex:(int)formIndex withFValue:(NSString *)strFValue{
sqlite3_stmt *statement = nil;
NSString *query;
if(sqlite3_open([[appDelegate databasePath] UTF8String],&database) == SQLITE_OK){
query = [NSString stringWithFormat: #"update ericsson_review_form_field_table set value = %# where fieldId = %# and form_index = %d",strFValue,strFieldId,formIndex];
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL)
== SQLITE_OK){
sqlite3_bind_text(statement, 1, [strFieldId UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 13, [strFValue UTF8String], -1, SQLITE_TRANSIENT);
if(sqlite3_step(statement))
return YES;
else
return NO;
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}
I don't see how the above could possibly work.
You're using sqlite3_bind_text, but you don't have any ? placeholders in your SQL to bind to. (You should check the return code from your sqlite3_bind_text calls and I'd be shocked if they're returning SQLITE_OK.)
You're binding the first item and the thirteenth item. The latter bind call, to the thirteenth ?, certainly wouldn't work unless you had at least thirteen ? placeholders.
You're returning immediately after calling sqlite3_step, never hitting your sqlite3_finalize statement and you'd undoubtedly leak memory as a result. You'd also never close the database if you got to these return statements after sqlite3_step.
You're testing if (sqlite3_step(...)). That doesn't make sense, because sqlite3_step always returns a non-zero value (either SQLITE_DONE upon success or some non-zero error code on error).
I'd suggest logging sqlite3_errmsg if any of the SQLite calls fail.
I might suggest changing the return value of the method to be the number of rows that were updated. This way, you can differentiate between (a) successful update; (b) no rows updated (but no errors); and (c) a failure. I might return negative value on error, zero if no rows matched the WHERE criteria, and a positive value, n, if n rows were successfully updated. I use sqlite3_changes to determine how many rows were updated.
Finally, I'd seriously advise against using stringWithFormat to build your SQL (at least if the string values include any user-provided input, because you expose yourself to quoting and/or SQL injection problems).
So, instead, I'd suggest:
/** Update fields
*
* #param strFieldId The fieldId column string value
* #param formIndex The form_index integer value
* #param strFValue The string to which the `value` column should be updated.
*
* #return Returns the number of rows updated. Return negative value on failure. Return zero if no rows matched the WHERE criteria.
*/
- (int)updateReviewFields:(NSString *)strFieldId andFormIndex:(int)formIndex withFValue:(NSString *)strFValue {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
sqlite3 *database;
NSString *databasePath = [appDelegate databasePath];
sqlite3_stmt *statement = nil;
int rowCount = -1;
int rc;
if ((rc = sqlite3_open([databasePath UTF8String], &database)) != SQLITE_OK) {
NSLog(#"Unable to open database: %# (%ld)", databasePath, (long)rc);
return rowCount;
}
const char *query = "update ericsson_review_form_field_table set value = ? where fieldId = ? and form_index = ?";
if ((rc = sqlite3_prepare(database, query, -1, &statement, NULL)) != SQLITE_OK) {
NSLog(#"sqlite3_prepare fail: %s (%ld)", sqlite3_errmsg(database), (long)rc);
sqlite3_close(database);
return rowCount;
}
if ((rc = sqlite3_bind_text(statement, 1, [strFValue UTF8String], -1, NULL)) != SQLITE_OK) {
NSLog(#"sqlite3_bind_text 1 fail: %s (%ld)", sqlite3_errmsg(database), (long)rc);
} else if ((rc = sqlite3_bind_text(statement, 2, [strFieldId UTF8String], -1, NULL)) != SQLITE_OK) {
NSLog(#"sqlite3_bind_text 2 fail: %s (%ld)", sqlite3_errmsg(database), (long)rc);
} else if ((rc = sqlite3_bind_int(statement, 3, formIndex)) != SQLITE_OK) {
NSLog(#"sqlite3_bind_int 3 fail: %s (%ld)", sqlite3_errmsg(database), (long)rc);
} else if ((rc = sqlite3_step(statement)) != SQLITE_DONE) {
NSLog(#"sqlite3_step fail: %s (%ld)", sqlite3_errmsg(database), (long)rc);
} else {
rowCount = sqlite3_changes(database);
}
sqlite3_finalize(statement);
sqlite3_close(database);
return rowCount;
}
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;
}