This is my code:
- (void) addOrder {
if(addStmt == nil) {
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));
}
sqlite3_bind_int(addStmt, 1, [menuID integerValue]);
sqlite3_bind_text(addStmt, 2, [itemName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_double(addStmt, 3, price );
sqlite3_bind_int(addStmt, 4, [quantity integerValue]);
sqlite3_bind_text(addStmt, 5, [spiciness UTF8String],-1,SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
menuID = sqlite3_last_insert_rowid(database);
//Reset the add statement.
sqlite3_reset(addStmt);
}
My menuID is NSdecimalNumber.In the else portion
menuID = sqlite3_last_insert_rowid(database); I got error as "Implicit conversion of sqlite3_int64 to NsdecimalNumber is disallowed with ARC.
How could I remove this error?Please help..
As you said that menuID is NSDecimalNumber than It should be like,
menuID = [NSDecimalNumber numberWithInt:sqlite3_last_insert_rowid(database)];
As it appears to be a 64 bit int, and iOS is a 32 bit system, you might want to use:
menuID = [NSDecimalNumber numberWithLongLong:sqlite3_last_insert_rowid(database)];
Related
I have an issue where I am trying to insert data from NSMutableArray in to my database. Here is what I have so far:
- (void)insertList:(NSString*) strListName ArrayOfData:(NSMutableArray*) dataArray{
sqlite3 *database = nil;
sqlite3_stmt *addStmt = nil;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"customlists.sqlite"];
if(sqlite3_open([defaultDBPath UTF8String], &database) == SQLITE_OK)
{
for (int i = 0; i < dataArray.count; i++)
{
PageData *pageDta = [PageData new];
pageDta = [dataArray objectAtIndex:i];
if(addStmt == nil) {
const char *sql = "insert into NewList(ListName, PageName, PageNumber, id) Values(?, ?, ?, ?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [strListName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [pageDta.strNamebyFilter UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 3, [pageDta.strPageNuber UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(addStmt, 4, i);
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
sqlite3_last_insert_rowid(database);
//Reset the add statement.
sqlite3_reset(addStmt);
}
}
else
{
NSLog(#"Error while opening database '%s'", sqlite3_errmsg(database));
}
sqlite3_close(database);
}
But after calling this function, the database is empty. Could someone help me to find the cause of this issue and potential remedies?
The main problem is simple - you are trying to write to a database in the app's bundle. This isn't allowed. An app's bundle is read-only on a real device (though it is writable in the simulator). The proper thing to do is copy the database from the resource bundle to a writable area of the app's sandbox the first time the app runs. Then every use of the database is done with the copy.
It would also be cleaner to prepare the statement before the for loop. No need to keep checking if it has been setup every loop iteration.
You make a call to sqlite3_last_insert_rowid but don't do anything with the value. What's the point?
You never finalize the statement after the loop is complete. You need to do that.
And you don't close the database when you are done.
change this line :
const char *sql = "insert into NewList(ListName, PageName, PageNumber, id) Values(?, ?, ?, ?)";
to :
NSString *insertSQL = [NSString stringWithFormat: #"NSString stringWithFormat: "INSERT INTO NewList(ListName, PageName, PageNumber, id) VALUES(\"%#\", \"%#\", \"%#\", \"%#\")" ,strListName, pageDta.strNamebyFilter, pageDta.strPageNuber, addStmt];
const char *sql = [insertSQL UTF8String];
I've rewrite function to:
if(sqlite3_open([defaultDBPath UTF8String], &database) == SQLITE_OK)
{
for (int i = 0; i < dataArray.count; i++)
{
PageData *pageDta = [PageData new];
pageDta = [dataArray objectAtIndex:i];
if(addStmt == nil) {
const char *sql = [[NSString stringWithFormat:#"INSERT INTO NewList (ListName, PageName, PageNumber) values('%#', '%#', '%#')",strListName,pageDta.strNamebyFilter, pageDta.strPageNuber] UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [strListName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [pageDta.strNamebyFilter UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 3, [pageDta.strPageNuber UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
//Reset the add statement.
sqlite3_reset(addStmt);
}
sqlite3_finalize(addStmt);
}
else
{
NSLog(#"Error while opening database '%s'", sqlite3_errmsg(database));
}
sqlite3_close(database);
but result is the same :(
This is my code :
- (void) addOrder {
if(addStmt == nil) {
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, [menuID integerValue]);
sqlite3_bind_text(addStmt, 2, [itemName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_double(addStmt, 3, price );
sqlite3_bind_int(addStmt, 4, [quantity integerValue]);
sqlite3_bind_text(addStmt, 5, [spiciness UTF8String],-1,SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
menuID = [NSDecimalNumber numberWithLongLong:sqlite3_last_insert_rowid(database)];
//Reset the add statement.
sqlite3_reset(addStmt);
}
Here data is inserted into DB but got the error "Constraint Failed"
hi may b this code will help you. insert data with this style.
sqlite3_stmt *stment;
stment =nil;
NSString *sql=[NSString stringWithFormat:#"insert into DateSave(Date,Name) Values('%#','%#')",Date,strTestName];
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &stment, NULL) == SQLITE_OK)
{
sqlite3_step(stment);
testID =sqlite3_last_insert_rowid(database);
}
}
sqlite3_finalize(stment);
sqlite3_close(database);
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)"])
Hello I'm trying to save string into SQLite database, but nothing happens. I have a string:
"tret44404%40ukr.net%3A100001740940428%3A06Kz8p1Xbk0PzpH%2F%3A0%3Av_1%2Cajax_1%2Cwidth_320%2Cpxr_1%2Cgps_1%3A1307716802"
I'm trying to save it to database but it saving string as:
"tret44404
80792kr.net-0X1.FD428P+01000017409404280X1.B2C260000001P-100906Kz8p1Xbk0PzpH0.0000000X1.149242P-104700X1.400000018P-1040v_1灠ajax_1Ῐwidth_320"
A method how I save string:
- (void) addCookie {
if(addStmt == nil) {
const char *sql = "insert into FaceBookCookies(userId, created, domain, Expires, HttpOnly, Name, Path, Value) Values(?, ?, ?, ?, ?, ?, ?, ?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_int(addStmt, 1, userID);
sqlite3_bind_int(addStmt, 2, created);
sqlite3_bind_text(addStmt, 3, [domain UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_double(addStmt, 4, [Expires timeIntervalSince1970]);
sqlite3_bind_text(addStmt, 5, [HttpOnly UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(addStmt, 6, [Name UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(addStmt, 7, [Path UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(addStmt, 8, [Value UTF8String], -1, SQLITE_STATIC); //here is a String...
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
userID = sqlite3_last_insert_rowid(database);
//Reset the add statement.
sqlite3_reset(addStmt);
}
Please help how to fix it...
You must probably remove the percent escapes before saving. Do it like this,
sqlite3_bind_text(addStmt, 8, [[Value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], -1, SQLITE_STATIC);
i had the sqlite statement ready for update..but i am confuse about grabbing text from uitextview and updating it..and i waned to update it using a uibutton..how do i carry on after creating the sql statement???kinda lost..any new solution is appreciate..
- (void) saveAllData {
if(isDirty) {
if(updateStmt == nil) {
const char *sql = "update Snap Set snapTitle = ?, snapDesc = ?, Where snapID = ?";
if(sqlite3_prepare_v2(database, sql, -1, &updateStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating update statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(updateStmt, 1, [snapTitle UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 2, [snapDescription UTF8String], -2, SQLITE_TRANSIENT);
sqlite3_bind_int(updateStmt, 3, snapID);
if(SQLITE_DONE != sqlite3_step(updateStmt))
NSAssert1(0, #"Error while updating. '%s'", sqlite3_errmsg(database));
sqlite3_reset(updateStmt);
isDirty = NO;
}
//Reclaim all memory here.
[snapTitle release];
snapTitle = nil;
[snapDescription release];
snapDescription = nil;
//isDetailViewHydrated = NO;
}
}
Instead of sqlite3_reset(updateStmt) I use sqlite3_finalize(updateStmt) and the code runs fine.