I am using the below function in my app,and i have started using the sq-lite recently and i would like to get your opinion that i am going with that correctly or not.
Since i am facing db locked issue in my app when searched i found that i need to use sqlite3 finalise statement.
what i am not sure is do i need to place one finalise statement for each sqlite3 prepare statement
Please let me know
- ( BOOL ) addNewCate:(NSString*)dbPath:(NSString*)title:(NSString*)tierOneID:(NSString*)tierTwoID{
BOOL returnVal = NO;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
const char *sql = "insert into storyboard_phrases(phrase) Values(?)";
sqlite3_stmt *addStmt;
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) == SQLITE_OK){
sqlite3_bind_text(addStmt, 1, [title UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(addStmt) != SQLITE_DONE ) {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
} else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
int ph_id = sqlite3_last_insert_rowid(database);
int sub_category_id = [tierTwoID intValue];
int main_category_id = [tierOneID intValue];
addStmt = nil;
sql = "insert into phrase_reference(phrase_id, sub_category_id,main_category_id) Values(?,?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) == SQLITE_OK){
sqlite3_bind_int(addStmt, 1, ph_id);
sqlite3_bind_int(addStmt, 2, sub_category_id);
sqlite3_bind_int(addStmt, 3, main_category_id);
}
if(sqlite3_step(addStmt) != SQLITE_DONE ) {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
} else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
returnVal = YES;
}
}
sqlite3_finalize(addStmt);
}
sqlite3_close(database);
return returnVal;
}
hii you get the locked issues in log right, that means your database is open and you doing some changes in that database so close database and try again to run application and insert in table...
hope this will help you..
Related
-(IBAction)btnAddToFavorite:(id)sender
{
[self insertDataToFavourites:[[tempDict objectForKey:#"pageid"]intValue]:[tempDict objectForKey:#"desc"]];
}
-(void)insertDataToFavourites:(int)pageid :(NSString *)description
{
sqlite3_stmt *insertStatement = nil;
NSString *sql;
int returnvalue;
sql = [NSString stringWithFormat:#"insert into AddFavorite (Id,Description) VALUES (?,?)"];
returnvalue = sqlite3_prepare_v2(database, [sql UTF8String], -1, &insertStatement, NULL);
NSLog(#"\nFavorite ID is:--> %d &\nDescription is:--> %#",[[tempDict valueForKey:#"pageid"] intValue] ,[tempDict valueForKey:#"desc"]);
if (returnvalue == 1){
NSAssert1 (0,#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_bind_text(insertStatement, 1,[[tempDict objectForKey:#"pageid"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insertStatement, 2,[[tempDict objectForKey:#"desc"] UTF8String], -1, SQLITE_TRANSIENT);
if (SQLITE_DONE != sqlite3_step(insertStatement)){
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
else{
sqlite3_reset(insertStatement);
}
sqlite3_finalize(insertStatement);
}
This is a code to insert data into database. It is showing data like this, when i check database using select query.
Can anybody tell me where is the mistake ?
Thanks.
try to use the pageid method variable and not your dict, maybe the dict is wrong. On the other hand you insert for id
sqlite3_bind_text(insertStatement, 1,[[tempDict objectForKey:#"pageid"] UTF8String], -1, SQLITE_TRANSIENT);
i think this might be not correct.
For test case you can insert in SQLiteManager as sqlstatement
insert into AddFavorite (Id,Description) VALUES (1,'TestDescription');
to check if the statement is correct.
I would use this code to insert your values, if id is an int in your database
-(void)insertDataToFavourites:(int)pageid :(NSString *)description
{
sqlite3 *database;
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "INSERT INTO AddFavorite (Id,Description) VALUES (?,?);";
sqlite3_stmt *compiled_statement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiled_statement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiled_statement, 1, pageid);
sqlite3_bind_text(compiled_statement, 2, [description UTF8String] , -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiled_statement) != SQLITE_DONE ) {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
} else {
NSLog( #"Insert into row id = %lld", sqlite3_last_insert_rowid(database));
}
sqlite3_finalize(compiled_statement);
}
sqlite3_close(database);
}
Please find the below function.it works fine for the first time.
I mean , when i add a text it works for the first time , then when i try to add a new text again , it give me like "DB is locked".
I am not sure how it works for the first not again?
Please let me know what is the problem in my code.
//==================================================================
- ( BOOL ) addNewSimpleTemplates:(NSString*)dbPath:(NSString*)title{
//==================================================================
BOOL returnVal = NO;
NSString *maxValuePosition;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *selectSQL = [NSString stringWithFormat:#"select MAX(pr.position) FROM phrase_reference pr inner join storyboard_main_categories smc on smc.id = pr.main_category_id where smc.category_name = %#", #"'Simple Templates'"];
const char *sql = [selectSQL UTF8String];
sqlite3_stmt *selectStmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) == SQLITE_OK){
while(sqlite3_step(selectStmt) == SQLITE_ROW)
{
//
char *localityChars = (char*)sqlite3_column_text(selectStmt, 0);
if (localityChars == NULL)
maxValuePosition = nil;
else
maxValuePosition = [NSString stringWithUTF8String: localityChars];
// increment the postion value
int postion = [maxValuePosition intValue] + 1;
NSLog(#"%d look here %# gtitle", postion , title);
selectStmt = nil;
//saving a new simple phrase is started here
sql = "insert into storyboard_phrases(phrase) Values(?)";
if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) == SQLITE_OK){
sqlite3_bind_text(selectStmt, 1, [title UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(selectStmt) != SQLITE_DONE ) {
NSLog( #"Error: %s just here itself", sqlite3_errmsg(database) );
} else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
///
int phrase_id = sqlite3_last_insert_rowid(database);
int sub_category_id = 0;
selectStmt = nil;
NSString *selectSQL = [NSString stringWithFormat:#"select id from storyboard_main_categories where category_name = %#", #"'Simple Templates'"];
sql = [selectSQL UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectStmt) == SQLITE_ROW)
{
char *localityChars = (char*)sqlite3_column_text(selectStmt, 0);
NSString* main_category_id = [NSString stringWithUTF8String: localityChars];
sql = "insert into phrase_reference (phrase_id, sub_category_id,main_category_id, position) Values(?,?,?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) == SQLITE_OK){
sqlite3_bind_int(selectStmt, 1, phrase_id);
sqlite3_bind_int(selectStmt, 2, sub_category_id);
sqlite3_bind_int(selectStmt, 3, [main_category_id intValue]);
sqlite3_bind_int(selectStmt, 4, postion);
}
if(sqlite3_step(selectStmt) != SQLITE_DONE ) {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
}else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
returnVal = YES;
}
}
}
sqlite3_finalize(selectStmt);
selectStmt = nil;
/////
}
}
}
sqlite3_finalize(selectStmt);
}
NSLog(#"sdsdfsdsd closed");
sqlite3_close(database);
return returnVal;
}
I am not going deep within your code but make sure that -
Dont forget to finalize the statements before close the database.
And do reset after every execution of the sqlite3 statement
You are not using reset statement any where.. Try using reset statement..
I cant for the life of me see what it could be? Any Advice? Thanks
(void)setRegId: (NSInteger) _regId
{
NSInteger r_id = _regId;
NSInteger row = 1;
ret = sqlite3_open(dbName, &database);
if (ret != SQLITE_OK)
{
printf("Error opening the db: %s\n", sqlite3_errmsg(database));
sqlite3_close(database);
return;
}
sqlite3_stmt *compiledStatement = nil;
if (compiledStatement == nil) {
const char *sql = "UPDATE RegDB Set id = ? Where rowindex = ?";
if (sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL) != SQLITE_OK)
{
NSLog(#"Error: failed to prepare compiledStatement with message '%s'.",sqlite3_errmsg(database));
return;
}
}
sqlite3_bind_int(compiledStatement, 1, r_id);
sqlite3_bind_int(compiledStatement, 2, row);
int success = sqlite3_step(compiledStatement);
if (success == SQLITE_ERROR){
NSLog(#"Error: failed to update compiledStatement with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
if(sqlite3_close(database) != SQLITE_OK)
{
NSLog(#"Error: failed to closed DB with message '%s'.",sqlite3_errmsg(database));
}
}
You need to check that you are both sending the correct update statement, and that you are correctly reading the result.
Try logging your final statement (or at least the variables r_id and row). Use sqlite3 or SQLiteManager with Firefox to check changes in the database.
I have tried many ways to achieve this biut unable to delete row from sqlite, please help me to correct following piece of code
dbPath = [self applicationDocumentsDirectory];
NSLog(#"%#", dbPath);
dbPath=[dbPath stringByAppendingPathComponent:#"database"];
dbPath=[dbPath stringByAppendingPathComponent:#"OFFENDERSDB.sqlite"];
NSLog(#"database path --> %#", dbPath);
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = ("DELETE * from OFFENDERS_LIST where ID=%d ",2);
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
NSLog(#"offender deleted");
}
sqlite3_finalize(compiledStatement);
}
Thanx in advance
have you tried using:
sqlite3_exec(database, sqlStatement...
with your DELETE statement?
ALSO.... it's DELETE FROM.... not DELETE * FROM....
Snagged the following code from another place out on the internet for a more complete example...
sqlite3 *db;
int rc;
rc = sqlite3_open( "C:\\MyDatabase", &db );
if ( rc )
{
sqlite3_close(db);
}
else //Database connection opened successfuly
{
char *zErrMsg = 0;
rc = sqlite3_exec( db, "DELETE FROM yourTable", NULL, NULL, &zErrMsg );
if( rc != SQLITE_OK )
{
sqlite3_free( zErrMsg );
}
sqlite3_close(db);
}
i have a huge problem with my sqlite3 database on the iphone sdk 4. I can only write/read the database once! With the iphone sdk 3.2 everything had just worked fine.
After the first try i get the errormessage "SQLITE_BUSY".
Here's a snippet of my code i use:
-(void) addFavoriteOdv:(Odv*)odv name:(NSString*)name;
{
#synchronized(self)
{
if(name == nil)
name = odv.name;
NSString* rowId = [self addOdv:odv];
int existing = [self numberOfFavoriteOdvs:rowId];
if(existing == 0)
{
sqlite3 *database = [self getOpenDatabase];
const char *insertStatement = [#"insert into favoriteodvs(odv, name) values (?, ?)" UTF8String];
int retCode = 0;
sqlite3_stmt *statement;
retCode = sqlite3_prepare_v2(database, insertStatement, -1, &statement, NULL);
if(retCode == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [rowId UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [name UTF8String], -1, SQLITE_TRANSIENT);
if(sqlite3_step(statement)!= SQLITE_DONE)
{
NSLog(#"SQL Error: %s", sqlite3_errmsg(database));
NSLog(#"Inserting FavoriteOdv failed");
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
}
Has anybody an idea? I use the libsqlite3.dylib.
Thanks,
Sebastian
to reuse your prepared statement - you must call
sqlite3_reset(statement);
right after you're received "SQLITE_DONE" from sqlite3_step. After that you can bind another data and run your query again.
p.s. wrong:
const char *insertStatement = [#"insert into favoriteodvs(odv, name) values (?, ?)" UTF8String];
correct:
const char *insertStatement = "insert into favoriteodvs(odv, name) values (?, ?)";