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
Related
In My current ios application I have to add tables and insert data to the added table for new version.
By taking Upgrade into consideration I did it through the code itself Like below
-(void)lessThan100TableQuery
{
NSString *query=[NSString stringWithFormat:#"CREATE TABLE 'Table_Name' ('item_id' INTEGER PRIMARY KEY NOT NULL , 'item_section' INTEGER, 'item_no' INTEGER, 'bullet_no' VARCHAR, 'heading' INTEGER, 'hide_controls' INTEGER, 'description' VARCHAR);INSERT INTO 'Table_Name' VALUES(1,1,0,'',1,1,'Condition/adequacy of distributor''s/supply intake equipment');"
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
if(sqlite3_step(statement) != SQLITE_DONE) {
return NO;
}
sqlite3_finalize(statement);
}
}
(like above I add 100 rows I skipped them here)
But by calling the above method only the table get added without the values
I cross checked it by running the above query in sqlitemanager and working fine without any issue. It is not working in code.
Help me out folks
The sqlite3_prepare_v2() documentation says:
These routines only compile the first statement in zSql
To execute multiple statements, you have to use a loop, and use pzTail to skip over the previously-executed statement.
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
I'm using the following code to insert a row into a database. For some reason, sqlite3_last_insert_rowid returns the correct row ID for the first row inserted, but after that it always returns 0.
Between inserts other DB actions may have occurred, like a deletion of a row.
_scoresDB is an instance var.
Here's my insert code:
-(void)insertScore:(OKScore*)score
{
const char *dbpath = [[self dbPath] UTF8String];
if(sqlite3_open(dbpath, &_scoresDB) == SQLITE_OK) {
// Setup the SQL Statement
if(insertScoreStatement == nil) {
//OKLog(#"Preparing statement for cache score");
const char *insertSQL = "INSERT INTO OKCACHE(leaderboardID,scoreValue,metadata,displayString,submitted) VALUES(?,?,?,?,?);";
if(sqlite3_prepare_v2(_scoresDB, insertSQL, -1, &insertScoreStatement, NULL) != SQLITE_OK) {
OKLog(#"Failed to prepare score insert statement with message: '%s'", sqlite3_errmsg(_scoresDB));
return;
}
}
// Bind the score values to the statement
sqlite3_bind_int(insertScoreStatement, 1, [score OKLeaderboardID]);
sqlite3_bind_int64(insertScoreStatement, 2, [score scoreValue]);
sqlite3_bind_int(insertScoreStatement, 3, [score metadata]);
if([score displayString]) {
sqlite3_bind_text(insertScoreStatement, 4, [[score displayString] UTF8String], -1, SQLITE_TRANSIENT);
} else {
sqlite3_bind_null(insertScoreStatement, 4);
}
sqlite3_bind_int(insertScoreStatement, 5, (int)[score submitted]);
//Execute the SQL statement
if(sqlite3_step(insertScoreStatement) == SQLITE_DONE) {
int scoreID = sqlite3_last_insert_rowid(_scoresDB);
[score setOKScoreID:scoreID];
OKLog(#"Cached score : %#",score);
} else {
OKLog(#"Failed to store score in cache wihth error message: %s",sqlite3_errmsg(_scoresDB));
}
sqlite3_reset(insertScoreStatement);
sqlite3_clear_bindings(insertScoreStatement);
sqlite3_close(_scoresDB);
} else {
OKLog(#"Could not open cache DB insertScore");
}
}
You cannot keep a statement for a database that is already closed.
If you try to reuse that old statement, nothing will be inserted (neither into the old database, because it's closed, nor into the new database, because the statement doesn't know about it).
Before closing the database, you must free the statement with sqlite3_finalize.
I don't think you should be retaining your insertScoreStatement. You have already bound values to it, now you are binding more stuff onto it. I would make it a local variable (not a class one nor a property) like this:
// Setup the SQL Statement
sqlite3_stmt *insertScoreStatement
//OKLog(#"Preparing statement for cache score");
const char *insertSQL = "INSERT INTO OKCACHE(leaderboardID,scoreValue,metadata,displayString,submitted) VALUES(?,?,?,?,?);";
if(sqlite3_prepare_v2(_scoresDB, insertSQL, -1, &insertScoreStatement, NULL) != SQLITE_OK) {
OKLog(#"Failed to prepare score insert statement with message: '%s'", sqlite3_errmsg(_scoresDB));
return;
}
}
I have a method intended to insert in my sqlite database from a custom object:
- (void)insertCustomEntity:(CustomEntity *)customEntity
{
NSString *filePath = [FileMngr copyDatabaseToDocuments];
sqlite3 *database;
if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "INSERT OR REPLACE INTO Entities (id, type, timestamp, result) VALUES (?, ?, ?, ?)";
sqlite3_stmt *compiledStatement;
NSLog(#"Could not prepare statement: %s\n", sqlite3_errmsg(database));
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, customEntity.id);
sqlite3_bind_int(compiledStatement, 2, customEntity.type);
sqlite3_bind_int64(compiledStatement, 3, customEntity.timestamp);
sqlite3_bind_int(compiledStatement, 4, customEntity.result);
}
if(sqlite3_step(compiledStatement) == SQLITE_DONE) {
}
else {
NSLog(#"Step: %d\n", sqlite3_step(compiledStatement));
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
I've been doing tests for a while and data was being inserted, but suddenly it stopped to do and I'm now getting a 5 step code at my second NSLog. Why does this happen, if it was working previously? I tried several options I found in some posts, like placing the sqlite3_step(compiledStatement) inside the sqlite3_prepare_v2 but I keep being unable to insert. What I'm doing wrong?
Thanks in advance
I am not sure but it looks like some of your braces are mis-matched? Anyways, error code 5 indicates that your database is locked.
http://www.sqlite.org/c3ref/c_abort.html
Check if something else is accessing your database ( or your database is not getting closed in some situation in which case your code needs to change). Try the following solution to resolve it :-
sqlite3 database is getting locked
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.