I'm using SQLITE3 for database operation in iPhone application.
I've 2 table in database and I want to insert into 2 tables in different situation.
My problem is for first time the insertion operation works fine. If I try to insert into another table the value's get insert into last inserted table.
My code for Table1 is :
-(void)addToTable1
{
if(addStmt == nil) {
const char *sql = "insert into Table(T1_Name) Values(?)";
if(sqlite3_prepare_v2(database, sqlCurrency, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [T1_Name UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
rowID = sqlite3_last_insert_rowid(database);
sqlite3_reset(addStmt);
sqlite3_close(database);
}
Code for Table2 is :
-(void)addToTable2
{
if(addStmt == nil) {
const char *sql = "insert into Table2(T2_Name) Values(?)";
if(sqlite3_prepare_v2(database, sqlWeight, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [T2_Name UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
rowID = sqlite3_last_insert_rowid(database);
sqlite3_reset(addStmt);
sqlite3_close(database);
}
I'm not getting any clue why its happening.
You must reset addStmt to nil after you have freed it, otherwise the if(addStmt == nil) check will prevent the new statement from being used.
Furthermore, you must use sqlite3_finalize, not sqlite3_reset, before closing the database.
Related
I want to update the quantity if the menuid is already available otherwise add a new row.
I used the following code.But no row is added or updated.
sqlite3 *database;
sqlite3_stmt *addStmt=nil;
if (selection== nil) {
selection =#"Medium";
}
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *select="select quantity from item where menuid = ?";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, select, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
menuID= [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
char *quant = (char *)sqlite3_column_text(selectstmt,1);
quantity=[NSString stringWithUTF8String:(char *)quant];
// [self.ids addObject:menuID];
}
sqlite3_reset(selectstmt);
}
NSString *quant=[NSString stringWithFormat:#"%#",quantity];
if (quant == #"") {
if (addStmt == nil) {
// const char *sql = "delete from item";
const char *sql = "insert into item(menuid,itemName,price,quantity,spiciness) Values( ?, ?, ?, ?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
// NSLog(#"ADDSTMT:%#",addStmt);
sqlite3_bind_int(addStmt, 1, [itemId integerValue]);
sqlite3_bind_text(addStmt, 2, [name UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_double(addStmt, 3, [priceItem doubleValue] );
sqlite3_bind_int(addStmt, 4, number);
sqlite3_bind_text(addStmt, 5, [selection UTF8String],-1,SQLITE_TRANSIENT);
NSLog(#"Name:%#",name);
NSLog(#"MENU IDe%#",priceItem);
if(SQLITE_DONE != sqlite3_step(addStmt)){
// NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
menuID = [NSDecimalNumber numberWithLongLong:sqlite3_last_insert_rowid(database)];
//Reset the add statement.
sqlite3_reset(addStmt);
}
else{
if (addStmt == nil) {
// const char *sql = "delete from item";
const char *sql = "update item set quantity= ? where menuid = ?";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
// NSLog(#"ADDSTMT:%#",addStmt);
sqlite3_bind_int(addStmt, 2, [itemId integerValue]);
number=number+[quant intValue];
sqlite3_bind_int(addStmt, 1, number);
NSLog(#"Name:%#",name);
NSLog(#"MENU IDe%#",priceItem);
if(SQLITE_DONE != sqlite3_step(addStmt)){
// NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
menuID = [NSDecimalNumber numberWithLongLong:sqlite3_last_insert_rowid(database)];
//Reset the add statement.
sqlite3_reset(addStmt);
sqlite3_close(database);
}
}
I might be just lacking proper understanding of your code but it doesn't look like you're beginning and then committing a transaction in there. I might be way off base though as I've never inserted a row without using a transaction.
I found it my self:
Changed select statement to:
NSString *sqlStmt=[NSString stringWithFormat:#"select quantity from item where menuid = %# and spiciness = '%#'",itemId,selection];
Also changed the if Condition of insert statement to
if ([quanty isEqualToString:#"(null)"])
I want to make it able in my app to insert data to sqlite database, and if the id for example is exist so to update this row.
i done the create with :
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *insertStmt = nil;
if(insertStmt == nil)
{
const char *insertSql = "INSERT INTO Category (id,name) VALUES(?,?)";
if(sqlite3_prepare_v2(database, insertSql, -1, &insertStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating insert statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_int(insertStmt, 1, 135);
sqlite3_bind_text(insertStmt, 2, [#"fds" UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(insertStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
//NSLog("Inserted");
//Reset the add statement.
sqlite3_reset(insertStmt);
insertStmt = nil;
}
sqlite3_close(database);
Use the OR REPLACE qualifier:
INSERT OR REPLACE INTO Category ...
This relies on the existence of a UNIQUE constraint (usually the primary key) containing just the id column.
You can use following code for update:
-(void) Update:(NSString *)query {
sqlite3_stmt *statement=nil;
NSString *path = [self GetDatabasePath:DataBaseName] ;
if(sqlite3_open([path UTF8String],&databaseObj) == SQLITE_OK)
{
if(sqlite3_prepare_v2(databaseObj, [query UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_step(statement);
}
sqlite3_finalize(statement);
}
if(sqlite3_close(databaseObj) == SQLITE_OK){
}else{
NSAssert1(0, #"Error: failed to close database on memwarning with message '%s'.", sqlite3_errmsg(databaseObj));
}
}
I have a SQL database which I can display on a UITableView. But if try to add any object it is not updated in UITableView. It is updated only after application is restarted.
When I delete objects from UITableView there is inbuilt method which does deleting
is if (editingStyle == UITableViewCellEditingStyleDelete) is there any such methods
for adding objects also?
My addition methods are as follows:
static sqlite3 *addStmt = nil;
- (void) add_Place:(Place *)PlaceObj {
NSLog(#"Super add called");
//Add it to the database.
[PlaceObj addPlace];
//Add it to the coffee array.
[PlacesArray addObject:PlaceObj];
}
- (void) addPlace {
NSLog(#"addplace called");
if(addStmt == nil)
{
NSLog(#"inside addstmt");
const char *sql = "INSERT INTO places_table ( PlaceName, PlaceAddress) Values (?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
{
NSLog(#"error inside if loop");
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
}
NSLog(#"outside if Loop") ;
sqlite3_bind_text(addStmt, 1, [PlaceName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [PlaceAddress UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
{
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));;
}
// NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
{
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
PlaceID = sqlite3_last_insert_rowid(database);
NSLog(#"sqlite3_last_insert_rowid") ;
}
//Reset the add statement.
sqlite3_reset(addStmt);
}
You can do this in the following manner. After you add the object just call the ReloadData UITableView Method and it will reload the table again. So there is no need To restart the application again.
static sqlite3 *addStmt = nil;
- (void) add_Place:(Place *)PlaceObj {
NSLog(#"Super add called");
//Add it to the database.
[PlaceObj addPlace];
//Add it to the coffee array.
[PlacesArray addObject:PlaceObj];
[TableView ReloadData];
}
- (void) addPlace {
NSLog(#"addplace called");
if(addStmt == nil)
{
NSLog(#"inside addstmt");
const char *sql = "INSERT INTO places_table ( PlaceName, PlaceAddress) Values (?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
{
NSLog(#"error inside if loop");
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
}
NSLog(#"outside if Loop") ;
sqlite3_bind_text(addStmt, 1, [PlaceName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [PlaceAddress UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
{
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));;
}
// NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
{
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
PlaceID = sqlite3_last_insert_rowid(database);
NSLog(#"sqlite3_last_insert_rowid") ;
}
//Reset the add statement.
sqlite3_reset(addStmt);
}
Cheers
I think what you are looking for is insertRowsAtIndexPaths:withRowAnimation. This will add the rows with a smooth animation of your choosing. This will only work if your UITableViewDataSource is coded properly however.
hii every one
i am using following method to insert data into data base , but it will save the first entered value only all the time
the following method is in the insertUpdateDelete class
- (void) InsertRecord {
if(addStmt == nil) {
NSString *nsql = [NSString stringWithFormat:#"insert into tbl_Users(FirstName,MiddleName) Values('%#','%#')",strFirstName,strMiddleName];
const char *sql = [nsql UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
{
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
}
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
intID = sqlite3_last_insert_rowid(database);
//Reset the add statement.
sqlite3_reset(addStmt);
}
through following code i am calling this method, tfText[0] & tfText[1] are text field variable , problem is,, on every click of save after entering some data in text field, it will save only the first entered value into the data base
- (void) save_Clicked
{
iICS_testAppDelegate *appDelegate = (iICS_testAppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a Items Object.
insertUpdateDelete *objInsertUpdateDelete = [[insertUpdateDelete alloc] init];
objInsertUpdateDelete.strFirstName = tfText[0].text;
objInsertUpdateDelete.strMiddleName = tfText[1].text;
[appDelegate InsertRecord:objInsertUpdateDelete];
}
can any one help me,,,,thanx in advance
const char *addRecord = "insert into Test(taskname, desc) values(?, ?)";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, addRecord, -1, &statement, NULL) != SQLITE_OK)
{
NSLog(#"Error while Inserting Record :- '%s'", sqlite3_errmsg(database));
sqlite3_finalize(statement);
return -1;
}
sqlite3_bind_text(statement, 1, [Ttitle UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [Tdesc UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(statement))
{
NSLog(#"Error1 while Inserting Record :- '%s'", sqlite3_errmsg(database));
sqlite3_finalize(statement);
return -1;
}
else
{
NSLog(#"Record Inserted Successfully.");
sqlite3_finalize(statement);
return sqlite3_last_insert_rowid(database);
}
Trying to return whether a record exists in SQLite on the iPhone except I keep getting an 'unknown error'.
selectStmt is static sqlite3_stmt *selectStmt = nil; used here if(selectStmt) sqlite3_finalize(selectStmt); which only gets executed if the application terminates. This functionality works fine with delete statements and insert statements so I'm guessing it's something wrong with the below logic?
- (BOOL) doesBookExist {
if(selectStmt == nil) {
const char *sql = "select count(*) from books where isbn = ?";
if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating select statement. '%s'", sqlite3_errmsg(database));
}
//When binding parameters, index starts from 1 and not zero.
int count = sqlite3_bind_text(selectStmt, 1, [isbn UTF8String], -1, SQLITE_TRANSIENT);
if (SQLITE_DONE != sqlite3_step(selectStmt))
NSAssert1(0, #"Error while selecting. '%s'", sqlite3_errmsg(database));
sqlite3_reset(selectStmt);
return (count > 0);
}
sqlite3_bind_text returns a success/error code, not the result of any query. And step should return SQLITE_ROW, since you have one row of result data (regardless of whether the count is 0 or more). There seemed to be an error, because you were expecting SQLITE_DONE when the correct value was SQLITE_ROW. Then, to get the count, you need to use sqlite3_column_int after executing step. So something like:
int bind_res = sqlite3_bind_text(selectStmt, 1, [isbn UTF8String], -1, SQLITE_TRANSIENT);
if (SQLITE_OK != bind_res)
{
// log error, return...
}
// One row of result data, so step should return SQLITE_ROW
if (SQLITE_ROW != sqlite3_step(selectStmt))
{
NSAssert1(0, #"Error while selecting. '%s'", sqlite3_errmsg(database));
// log error, return
}
int count = sqlite3_column_int(selectStmt, 0);