I want to update the data into sqlite db.I tried and followed lot of links and methods for update data.But all these do not work out for me.
when i insert my data, following data inserted in db with no problem.
NSString *insertSQL = [NSString stringWithFormat:#"INSERT INTO BusinessCardAppOneTable (NamorTitofImginTxtFld ,TxtofTxtView ,ImaGe,Location,Date,Time)VALUES(?,?,?,?,?,?);"];
NOTE:For image i created the image folder(path) in DB.
Then i fetched and i displayed these data from DB to tableview.
Then i edited NamorTitofImginTxtFld,TxtofTxtView,Date,Time (These are in edit view controller-where i get the image,location,date,time,NamorTitofImginTxtFld,TxtofTxtView from tableview(fetch data))
After that i edited NamorTitofImginTxtFld,TxtofTxtView,date and time.Also if i want to set the date and time i should go to REMAINDER VIEW CONTROLLER(from remainder button of edit view controller to remainder view controller).Where i set the date and time picker.Once i set that and back to edit view controller i can see the edited part.
So my update query is
NSString *updateSQL = [NSString stringWithFormat:#"UPDATE BusinessCardAppOneTable SET NamorTitofImginTxtFld = ?, TxtofTxtView = ?,Date = ? WHERE Time =? "];
If i only edited NamorTitofImginTxtFld and TxtofTxtView,these only updated in db.But if i edited all NamorTitofImginTxtFld , TxtofTxtView with date and time all these do not update.
Anyone can explain about the database update and how to update these 4 columns in db successfully?
I submitted the 3 various options
first //it match up ur answer
update BusinessCardAppOneTable set NamorTitofImginTxtFld = ?, TxtofTxtView = ?, Date = ?, Time =? where id = 5 // here u need to identify your id, if it is correct it surely update
second //it is related to your answer
Yes You can use Parametrized Query as Below :-
NSString *sqlString = #"update BusinessCardAppOneTable set NamorTitofImginTxtFld = ?, TxtofTxtView = ?, Date = ?, Time =? where id = ?";
sqlite3_stmt *stmt;
if(sqlite3_prepare(database, [sqlString UTF8String], -1, &stmt, NULL) != SQLITE_OK)
{
//Handle Error
}
if(sqlite3_bind_text(stmt, 1, [record.name UTF8String],[record.type UTF8String],[record.state UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
// Handle Error
}
if(sqlite3_bind_int(stmt, 2, record.key) != SQLITE_OK)
{
// Handle Error
}
if (sqlite3_step(statement) != SQLITE_DONE)
{
// Handle Error
}
And your Parametrized Code is ready.
in third choice
u follow the link Sqlite3 update query not working in ios app
Related
i have created sqlite database as follow
NSString * sqlStmt =#"CREATE TABLE IF NOT EXISTS SONGS (ID INTEGER PRIMARY KEY AUTOINCREMENT, MOVIENAME TEXT, SONGNAME TEXT)";
after deleting row 7 in database the id values are 1,2,3,4,5,6,8,9... by using following code where idNumber =7.
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &_SQliteDB) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"delete from SONGS where ID=%d",idNumber];
const char *del_stmt = [sql UTF8String];
char *error ;
if (sqlite3_exec(_SQliteDB,del_stmt, NULL, NULL, &error) == SQLITE_OK)
{
NSLog(#"sucessfully delete");
} else
{
NSLog(#"unable to delete");
}
sqlite3_close(_SQliteDB);
}
else
{
NSLog(#"unable to open");
}
i need to rearrange that order as sequentially as 1,2,3,4,5,6,7,8?
Any help would be appreciated.
You shouldn't re-order IDs, because other tables may have reference for this ID. Because if any how you are able to do that then next problem will arise in front of you.
For example:- You have rows 1, 2, 3 and you delete 2, then you have 1, 3. And you sorted this any how. Now Issue is when you going to add new item it starts with 4 not 3.
In your case, I recommend using the Row_Number if it's for a display reason.
There's no problem having gaps in a database.
If you want the order as sequentially, ORDER BY is what you are looking for.
After deleting, retrieve records using select query as shown below :
NSString *select = #"SELECT * FROM SONGS ORDER BY ID"
For more detail about ORDER BY , refer to link1 and for how to use it in iOS, refer to link2
You must define all data from database to new array or list.After that you must delete table and rewrite all data from array or list to database.
You can look for android studio solution ;
https://stackoverflow.com/a/57862686/8363647
I have a area table in sqlite database. Everytime i am just performing insert operation onto the sqlite database. How can i check if any record exists or not. If not exist simply insert. If exist then update records.
Please help me.
you can do easily "insert or ignore into tbl_name"
here you can see the example
http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app
this would be usefull for you....
http://www.sqlite.org/lang_conflict.html
Yes, you can do that with a single query.
INSERT ON CONFLICT IGNORE should help you: http://www.sqlite.org/lang_conflict.html
Put a unique key on the name, this will create a conflict when you try inserting a record if the name already exists.
The default is ABORT, so without the IGNORE, the statement will return an error. If you don't want that, use IGNORE.
You can do INSERT OR REPLACE if you have a primary key on the table. For example:
sqlite3 *database = NULL;
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *path = [documentsPath stringByAppendingPathComponent:#"test.sqlite"];
int rc = sqlite3_open([path UTF8String], &database);
NSAssert(rc == SQLITE_OK, #"Open failed");
// note, use PRIMARY KEY when creating table
rc = sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS test (animal TEXT PRIMARY KEY, sound TEXT)", NULL, NULL, NULL);
NSAssert(rc == SQLITE_OK, #"Create failed: %s", sqlite3_errmsg(database));
// create a record that will be replaced by the subsequent `INSERT OR REPLACE`
rc = sqlite3_exec(database, "INSERT INTO test (animal, sound) VALUES ('dog', 'meow')", NULL, NULL, NULL);
NSAssert(rc == SQLITE_OK, #"INSERT failed: %s", sqlite3_errmsg(database));
// this will REPLACE entry if value with same PK found, otherwise it would INSERT
rc = sqlite3_exec(database, "INSERT OR REPLACE INTO test (animal, sound) VALUES ('dog', 'woof')", NULL, NULL, NULL);
NSAssert(rc == SQLITE_OK, #"INSERT failed: %s", sqlite3_errmsg(database));
// now retrieve values and make sure it worked like we thought it would
sqlite3_stmt *statement = NULL;
rc = sqlite3_prepare_v2(database, "SELECT animal, sound FROM test", -1, &statement, NULL);
NSAssert(rc == SQLITE_OK, #"prepare SELECT failed: %s", sqlite3_errmsg(database));
while ((rc = sqlite3_step(statement)) == SQLITE_ROW) {
const unsigned char *animal = sqlite3_column_text(statement, 0);
const unsigned char *sound = sqlite3_column_text(statement, 1);
NSLog(#"%s goes %s", animal, sound);
}
NSAssert(rc == SQLITE_DONE, #"step failed: %s", sqlite3_errmsg(database));
sqlite3_finalize(statement);
sqlite3_close(database);
And that will report that the INSERT OR REPLACE replaced the previous value rather than inserting second record:
2013-11-21 08:59:25.285 AnimalSounds[53549:70b] dog goes woof
If you don't have primary key, rather than this simple INSERT OR REPLACE, you'd have to break it into two steps, either:
Look for record with SELECT: If found, do UPDATE; if not found, do INSERT.
First DELETE any records that would match whatever criteria you want, and then do INSERT.
This first approach is a bit safer, but you could use the second approach if you had to (though you would probably use transactions a do a ROLLBACK if you had any problems). Needless to say, the INSERT OR REPLACE approach is even easier, but requires a primary key.
First call get record query in Database. Here I am add a example, I am checking that user login information available in database or not. So add below code. IF User record is available than i get record array otherwise nil.
+(NSArray*)getTBL_LOGIN
{
NSMutableArray *Favourite=[[NSMutableArray alloc]init];
sqlite3 *database;
TabBarAppDelegate *x=(TabBarAppDelegate*)[[UIApplication sharedApplication]delegate];
if(sqlite3_open([[x dataBasePath] UTF8String],&database) == SQLITE_OK) {
NSString *str = [NSString stringWithFormat:#"select * from tbl_login"];
const char *sqlStmt=[str UTF8String];
sqlite3_stmt *compiledStmt;
if(sqlite3_prepare_v2(database, sqlStmt, -1, &compiledStmt, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStmt)==SQLITE_ROW)
{
NSString *uid=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStmt, 0)];
NSString *username=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStmt, 1)];
NSDictionary *d=[NSDictionary dictionaryWithObjectsAndKeys:uid,#"uid",username,#"username",nil];
[Favourite addObject:d];
}
}
sqlite3_finalize(compiledStmt);
}
sqlite3_close(database);
if([Favourite count]>0)
{
NSArray *ar=[NSArray arrayWithArray:Favourite];
return ar;
} else {
return nil;
}
}
If you get the record count >=1 then record exist so you have to call update query if you get record count 0 than record is not available in database so you have to call insert query
In a situation where I imported all updates into another database table, I could use following:
-- Existing table: t(uc UNIQUE, v1, v2, v3);
-- Updates table: ut(uc UNIQUE, v2);
INSERT OR REPLACE INTO t
SELECT ut.uc, et.v1, ut.v2, et.v3 FROM ut
LEFT JOIN t AS et ON ut.uc=et.uc;
This statement will insert new rows from ut into t. Existing rows are replaced with a row containing new data from ut and existing data from t.
For this to work, you must have a UNIQUE column (which makes sense as you are looking for a row update or insert a new one), and have new data available so it can be queried (in same or another database).
This worked for me, hope it may help you.
Another solution, maybe with better performance is using two statements:
UPDATE t SET v1='some value', v2=123 WHERE unique_col='some_id';
INSERT OR IGNORE t(v1, v2, unique_col) VALUES('some value', 123, 'some_id');
UPDATE will become a null operation when 'some_id' is not found.
INSERT will ignore all existent 'some_id'.
My iOS app uses SQLite3 databases and so far I have successfully managed to create tables, insert values and then later select them.
However, now I want to update. I tried this:
UPDATE field WHERE _id = 5 (name,type,state) VALUES (?,?,?)
But SQLite tells me a syntax error exists near the WHERE
As I understand that SQLite may not support the above syntax preferring it formatted as below.
UPDATE field SET name= "Upper" type= "Pigs" state=1 WHERE _id = 5;
However notice in the second statement there are no (?,?,?) (parameterized query I believe its called) for dynamically inserting values into the SQL string. Tell me is this possible and if so how?
Yes You can use Parametrized Query as Below :-
NSString *sqlString = #"UPDATE field SET name=?, type=?, state=? where _id=?";
sqlite3_stmt *stmt;
if(sqlite3_prepare(database, [sqlString UTF8String], -1, &stmt, NULL) != SQLITE_OK)
{
//Handle Error
}
if(sqlite3_bind_text(stmt, 1, [record.name UTF8String],[record.type UTF8String],[record.state UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
// Handle Error
}
if(sqlite3_bind_int(stmt, 2, record.key) != SQLITE_OK)
{
// Handle Error
}
if (sqlite3_step(statement) != SQLITE_DONE)
{
// Handle Error
}
And your Parametrized Code is ready.
You want
update field set name = ?, type = ?, state = ? where id = 5
i have this odd bug where i'm querying my table 'Children' with quite a complex query. It works fine, but for some reason it bugs a this other view from updating the database. You see this database holds stickers and one easy way to give them is to access this admin page, which is where its bugging. I can query the information fine, BUT ! when i update the table it hates and doesn't work. But its strange inside the core view controller it doesn't bug when i update the table there. I narrowed down the code to the cause of this problem:
-(void)leaderboardsystem
{
NSString *nexttargetsql = [NSString stringWithFormat:#"SELECT * FROM Children WHERE Completed > %d OR (Completed = %d AND Current_Stickers > %d) ORDER BY Completed ASC, Current_Stickers ASC LIMIT 1",completecount,completecount,stickercount]; //Queries table for the childs name and returns more data.
NSString *behindyousql = [NSString stringWithFormat:#"SELECT * FROM Children WHERE Completed < %d OR (Completed = %d AND Current_Stickers < %d) ORDER BY Completed DESC, Current_Stickers DESC LIMIT 1",completecount,completecount,stickercount];
nexttarget.text = [self leaderboardQuery:nexttargetsql];
behindyou.text = [self leaderboardQuery:behindyousql];
}
-(NSString*)leaderboardQuery:(NSString*)sql//does the querying
{
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(Childdb, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
char *ffield1 = (char *) sqlite3_column_text(statement, 0);
NSString *ffield1Str = [[NSString alloc]initWithUTF8String:ffield1];
char *ffield2 = (char *) sqlite3_column_text(statement, 8);
NSString *ffield2Str = [[NSString alloc]initWithUTF8String:ffield2];
char *ffield3 = (char *) sqlite3_column_text(statement, 10);
NSString *ffield3Str = [[NSString alloc]initWithUTF8String:ffield3];
NSLog(#"Name:%#",ffield1Str);
NSLog(#"this is completecount: %#", ffield2Str);
NSLog(#"this is stickcount: %#",ffield3Str);
return ffield1Str;
}
}
return NULL;
}
whenever i call the method leaderboardsystem it causes this bug, but if i don't then it works fine ! funny enough, i was a little surprised to be honest. It surprises me because it affects a completely different view controller that has no connection to the main view. The table layout is:
[self createTable:#"Children" withField1:#"Name" withField2:#"Password" withField3:#"House" withField4:#"Sticker Collection" withField5:#"Tickets Gathered" withField6:#"Tickets Removed" withField7:#"Last Ticket Scanned" withField8:#"Current Tickets" withField9:#"Completed" withField10:#"Complete" withField11:#"Current_Stickers"];
This is the updating code that seems to fail when i include the leaderboard system in the main view(this is on a completely different view controller)
-(void)UpdateDatabase//update table, if value has been incremented
{
NSString *sql = [NSString stringWithFormat:#"UPDATE Children SET 'Current Tickets' = %d, 'Tickets Removed' = %d, 'Tickets Gathered' = %d WHERE Name = '%#'",[self.currenttickets.text integerValue], [self.removedtickets.text integerValue], [self.totaltickets.text integerValue], name];
[self updatetable:sql];
}
-(void)updatetable:(NSString*)sql
{
char *err;
if (sqlite3_exec(Childdb, [sql UTF8String], NULL, NULL, &err)!=SQLITE_OK) {
sqlite3_close(Childdb);
NSAssert(0, #"Could not update Table");
} else {
NSLog(#"Table updated");
}
}
I'm trying not to overload the description here and keeping it brief my program is quite large, if you require any more information let me know. BUT i guarantee that the leaderboard system is causing the problem. Thanks a million if you can solve this problem, been working on it all day ! :(
ALSO it also disturbs the place where i add records to the table, so the updating code is not causing it. Its that leaderboard query, no idea why :(
Okay, well i didn't want to do this. But instead of having a method to manage the query, i just repeated it twice, inside the method, but it worked ! Not sure what was wrong with it. Seems no one else could help me so, i'll just leave it to that.
You need to call sqlite3_finalize(Childdb). It would look something like the following:
-(NSString*)leaderboardQuery:(NSString*)sql//does the querying
{
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(Childdb, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
...
}
}
sqlite3_finalize(Childdb);
return NULL;
}
This is a really simple example because there is no error handling. The documentation that describes this is the following (located here):
*ppStmt is left pointing to a compiled prepared statement that can be executed using sqlite3_step(). If there is an error, *ppStmt is set to
NULL. If the input text contains no SQL (if the input is an empty
string or a comment) then *ppStmt is set to NULL. The calling
procedure is responsible for deleting the compiled SQL statement using
sqlite3_finalize() after it has finished with it. ppStmt may not be
NULL.
This example code may help you: https://github.com/ccgus/fmdb/blob/master/src/FMDatabase.m#L519
On iOS, I want store user data in database using sqlite. For that design .Xib file username, password, DOB as text fields and take button, after fill all text fields when click the button all the data is stored in database.
I assume you already know how outlets work and how to get information from UI elements.
SQLite part. SQLite is very easy. You need to have an INSERT query, like this:
char *query = "INSERT INTO myTable (field1, field2) VALUES (?, ?)";
sqlite3_stmt *statem;
sqlite3_prepare_v2(myDB, query, -1, &statem, NULL);
sqlite3_bind_text(statem, 1, [[field1 text] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statem, 2, [[field1 test] UTF8String], -1, SQLITE_STATIC);
do {
int status = sqlite3_step(statem);
} whlie (status != SQLITE_DONE && status != SQLITE_ERROR);
You should set up the DB first but this can all be found in the documentation.