I am using sqlite database in my iphone app.
I am writing code for update record on certain condition. While my query is correct how can I detect that any row is updated or not..
I had tried SQLITE_DONE but it shows that query executed or not... What to use..
Here is my code..
const char *sqlStmt = [strQuery UTF8String];
if (sqlite3_prepare_v2(database, sqlStmt, -1, &compiledStatement, NULL) == SQLITE_OK) {
isSucceed = sqlite3_step(compiledStatement) == SQLITE_DONE;
//isSucceed = YES;
}
what will be in place SQLITE_DONE
I think you're looking for sqlite3_changes().
Related
I'm having two crashes show up in my logs using the following code to insert into my SQLite DB - the code works perfectly most of the time however clearly there is a something wrong that's causing the crash.
It crashes on either sqlite3_last_insert_rowid or sqlite3_close with EXC_BAD_ACCESS (I hold a reference to the SMSDatabase and it's in a singleton not sure why it would be deallocated) and SIGABRT (memory issue?)
- (NSInteger)query:(NSString *)query {
NSInteger lastRowID = 0;
if (sqlite3_open([self.databasePath UTF8String], &smsDatabase) == SQLITE_OK)
{
sqlite3_stmt *statement = nil;
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(smsDatabase, sql, -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE)
{
lastRowID = sqlite3_last_insert_rowid(smsDatabase);
}
}
sqlite3_finalize(statement);
}
sqlite3_close(smsDatabase);
return lastRowID;
}
Where am I going wrong?
sqlite3_close(smsDatabase); - isn't this outside your if statement, which means you are closing a database which may have never been opened ?
I can receive the data from .sql file(sqlite) in iOS5 , But in ios6. The app is getting hang..
If the query is select * from Table then works perfectly
If query is select *from Table order by ID DESC then the app is getting hang
some times the app hang in (sqlite3_open([dbPath UTF8String],&db) == SQLITE_OK)
some times hangs in
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
}
Finalize the statements and Close the connection properly each you perform an operation, then you should be fine with the sqlite. If the statements are not finalized then you get to states like SQLITE_BUSY,SQLITE_LOCKED which you need to handle. If the app is hanging that means your main thread is blocked. Following is a sample sqlite operation.
-(int)keyIdForImgId:(int)ImgId
{
#synchronized(self)
{
int keyId=0;
sqlite3 *database=nil;
if (sqlite3_open([[self getDBPath] UTF8String], &database) == SQLITE_OK) {
const char *sql = "SELECT keyId From SomeTableName WHERE imageId=?";
sqlite3_stmt *selectstmt=nil;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
sqlite3_bind_int(selectstmt, 1, ImgId);
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
keyId = sqlite3_column_int(selectstmt, 0);
}
}
sqlite3_finalize(selectstmt);
sqlite3_close(database);
}
return keyId;
}
}
Help please :-)
Following code is supposed to delete a record. It seems to execute OK, no error message and the NSLog shows "Record Deleted" message. However the record is not deleted. I have used Terminal to check and indeed the deleted record is still there. The puzzling part is that I have very similar code to add and count records and they all seem to work... I am not an SQL expert, so I am hoping that an expert in this crowd can see the error.
Thanks
(void) deleteRecord
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &wfDataBase) == SQLITE_OK)
{
NSLog(#"About to Delete Record %d",currentID);
NSString *querySQL = [NSString stringWithFormat: #"DELETE from wfDataBase WHERE ID = %d", currentID];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(wfDataBase, query_stmt, -1, &statement, NULL) == SQLITE_OK)
l_status.text = #"Record Deleted";
else
l_status.text = #"Can't Delete";
sqlite3_finalize(statement);
sqlite3_close(wfDataBase);
}
}
Are you sure you have evaluated (sqlite3_step(statement )) the compiled statement (sqlite3_prepare_v2(wfDataBase, query_stmt, -1, &statement, NULL)) before destroying it (sqlite3_finalize(statement))?
Note: I'm not an expert on SQLite (indeed I don't know anything about SQLite) but I guess this is the cause of the problem.
I want to completely clean all the contents in a SQLite3 table in my iPhone app. My MySQL experience told me that I should use TRUNCATE. But it seems that SQLite3 doesn't support TRUNCATE (at least I got an error when preparing statement when I use the sentence TRUNCATE my_table_Name).
So I turn to DELETE FROM. Two questions: 1) Will DELETE FROM clean my table in a thorough way? 2) I tried the following code and it worked. But I highly doubted that there are unnecessary or even wrong codes in it. Can anyone help me take a look at it?
Thanks in advance.
Di
-(void)deleteAllUser {
NSString *ns_sql = [NSString stringWithFormat:#"DELETE FROM %#", [Config USER_TABLE_NAME]];
const char *sql = [ns_sql cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *statement = nil;
sqlite3* db = ...; //get the database instance
if(sqlite3_prepare_v2(db, sql, -1, &statement, nil) != SQLITE_OK) {
return;
}
//Without this line, table is not modified
int code = sqlite3_step(statement);
if (code == SQLITE_ROW) {
//Do nothing here...
}
sqlite3_finalize(statement);
}
I think
if (code == SQLITE_ROW) {
//Do nothing here...
}
this code should be like
if (code == SQLITE_DONE) {
//Do nothing here...
}
If you want to get any message then you can return YES from here and NO from else(if you change return type to BOOL from void).This can help you in showing messaeges.
Until now all my database access has been reading, but now I need to update (and after this insert)
I have a database containing 'shows' in the app directory (read-only) and that's ok for me (I don't want to copy it to the documents folder as it's rather big and I don't need to change stuff in it.
But I want the user to select some shows as his favorite. Therefore I created a database with a table 'favorite_shows' in the documents folder. It contains 4 fields:
ID (prim key)
show_id
is_favorite
remarks (currently not yet in use)
The user is able to toggle the 'is_favorite' status ONCE, after that I'm getting an error when trying to update:
SQLITE_BUSY 5 /* The database file is locked */
This is my code:
if (sqlite3_open([databasePath UTF8String],&database) == SQLITE_OK){
sqlStatement = "select * from favorite_shows WHERE (show_id = ?)";
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, self.ID);
// search for a show
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// if we can find one, toggle the status
favID = sqlite3_column_int(compiledStatement, 0); // we need the primary key to update it
isFav = (sqlite3_column_int(compiledStatement, 2) == 1); // let's store the favorite status
sqlStatement = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, !isFav );
sqlite3_bind_int(compiledStatement, 2, favID);
int error = sqlite3_step(compiledStatement);
if (SQLITE_DONE != error) {
NSLog(#"error while updating favorite status");
}
}
}
//else : no records found indicating that this show hasn't been a favorite yet, so insert one as favorite
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
What is the reason that it's locked the second time ? Is there some other instruction to give besides :
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
to close everything ?
EDIT:
The BUSY is a result of re-using compiledStatement without deleting the previously compiled statment. You need to free resources properly using finalize and close functions.
Refer to the docs here. http://sqlite.org/c3ref/stmt.html
const char * select = "select * from favorite_shows WHERE (show_id = ?)";
const char * update = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";
sqlite3_stmt *selectStmt;
sqlite3_stmt *updateStmt;
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
if(sqlite3_prepare_v2(database, select, -1, &selectStmt, NULL) == SQLITE_OK) {
sqlite3_bind_int(selectStmt, 1, self.ID);
// search for a show
if(sqlite3_step(selectStmt) == SQLITE_ROW) {
// if we can find one, toggle the status
favID = sqlite3_column_int(selectStmt, 0); // we need the primary key to update it
isFav = (sqlite3_column_int(selectStmt, 2) == 1) ? 0 : 1; // Flip is_favorite value
sqlite3_finalize(selectStmt); // Delete the statement OR create a new one
if(sqlite3_prepare_v2(database, update, -1, &updateStmt, NULL) == SQLITE_OK) {
sqlite3_bind_int(updateStmt, 1, isFav );
sqlite3_bind_int(updateStmt, 2, favID);
int error = sqlite3_step(updateStmt);
if (SQLITE_DONE != error) {
NSLog(#"error while updating favorite status");
} else {
sqlite3_finalize(updateStmt);
}
}
} //else : no records found indicating that this show hasn't been a favorite yet, so insert one as favorite
}
sqlite3_close(database);
}