SQLStatement is getting rejected - ios

I'm trying to insert a user note into a sqliteDB through this method but for some reason, its not passing this if statement...
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK){}
I'm not sure but I think my SQLStatement is getting rejected or some reason.
(void) insertQuickNoteInDataBase:(NSString *)name :(NSString *)note{
sqlite3 * database;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "insert into detail(QuickNote) values (?), where name = ?";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_text(compiledStatement, 8, [note UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 2, [name UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(compiledStatement))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}

You need to log the error using sqlite3_errmsg. But the problem is most likely the comma in the query as well as the where clause. Insert statements should not have a where clause. Perhaps you mean to use an update:
"UPDATE detail SET QuickNote = ? WHERE name = ?"
Also, your calls to sqlite3_bind_xxx need to have the proper indexes. The bind indexes start at 1 and go up. You are using 8 then 2. You want 1 then 2.

Related

Sqlite update command is not working

When i try to update a table its giving me a
error message : near "(": syntax error
Please anybody suggest me to rectify this issue.
I am updating a table when i click the save button (Bar button item) on the tool bar which is placed below.
The problem is it's always going to else statement of sqlite3_step.
I am not getting whats the exact problem for this issue and the above mentioned error.
Any suggestions would be appreciated.
Following is my update method :
if ([databaseManager didExistDatabaseInDocumentDirectory] == YES)
{
const char *dbpath = [[databaseManager getDatabasePathFromDocument] UTF8String];
sqlite3_stmt *stmt;
if (sqlite3_open(dbpath, &scanningDB) == SQLITE_OK)
{
const char *update_stmt1 = "UPDATE FILES SET (documentType,orderNumber) VALUES (?,?) WHERE ID = ?";
sqlite3_prepare_v2(scanningDB, update_stmt1, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, [str UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [str1 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3,[num intValue]);
if(sqlite3_step(stmt)==SQLITE_DONE)
{
sqlite3_reset(stmt);
NSLog(#"Record Updated Successfully");
}
else
{
NSLog(#"Could not Update Record");
NSLog(#" error message %s",sqlite3_errmsg(scanningDB));
sqlite3_finalize(stmt);
sqlite3_close(scanningDB);
return NO;
}
sqlite3_finalize(stmt);
sqlite3_close(scanningDB);
}
else
return NO;
}
else
return NO;
Please correct your query with the following.
const char *update_stmt1 = "UPDATE FILES SET documentType = ? ,orderNumber = ? WHERE ID = ?
Hope this will help you.
Your update query is wrong.
UPDATE FILES SET (documentType,orderNumber) VALUES (?,?) WHERE ID = ?
Syntax:
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];
Your query:
UPDATE FILES SET documentType =?, orderNumber =? where ID =?, documentTypeString, Yourordernumber, yourID
Sample:
- (void) update
{
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
if(updateStatement == nil)
{
const char *sql = "UPDATE FILES SET documentType =?, orderNumber =? where ID =?";
if(sqlite3_prepare_v2(database, sql, -1, & updateStatement, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating update statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(documentType
, 1, [comment UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(orderNumber
, 2, [categoria UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(ID, 3, id);
if(SQLITE_DONE != sqlite3_step(updateStatement))
NSAssert1(0, #"Error while updating data. '%s'", sqlite3_errmsg(database));
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
//noteID = sqlite3_last_insert_rowid(database);
//Reset the update statement.
sqlite3_reset(updateStatement);
sqlite3_close(database);
deleteStatement = nil;
}
else
sqlite3_close(database);
}
Basic SQLite tutorial:
http://www.tutorialspoint.com/sqlite/index.htm

error: near "?": syntax error using sqlite and obj-c

After a suggestion on here I have tried to bind the values being passed into my queries, but I keep getting the syntax error: error: near "?": can someone explain why please?
NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:#"banklist" ofType:#"sqlite3"];
if(sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK)
{
{
// prep statement
sqlite3_stmt *statement;
NSString *querySQL = #"UPDATE ? SET recipe_name=? WHERE cell_id=?";
NSLog(#"query: %#", querySQL);
const char *query_stmt = [querySQL UTF8String];
// preparing a query compiles the query so it can be re-used.
sqlite3_prepare_v2(_database, query_stmt, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [del.dayName UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [info.name UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int(statement, 1, del.tableRowNumber);
// process result
if (sqlite3_step(statement) != SQLITE_DONE)
{
NSLog(#"error: %s", sqlite3_errmsg(_database));
}
sqlite3_finalize(statement);
}
{
// prep statement
sqlite3_stmt *statement;
NSString *querySQL = #"UPDATE ? SET recipe_id = (SELECT key FROM recipes WHERE name = ?.recipe_name)";
NSLog(#"query: %#", querySQL);
const char *query_stmt = [querySQL UTF8String];
// preparing a query compiles the query so it can be re-used.
sqlite3_prepare_v2(_database, query_stmt, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [del.dayName UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [del.dayName UTF8String], -1, SQLITE_STATIC);
// process result
if (sqlite3_step(statement) != SQLITE_DONE)
{
NSLog(#"error: %s", sqlite3_errmsg(_database));
}
sqlite3_finalize(statement);
}
}
sqlite3_close(_database);
You use sqlite3_bind_xxx for values in your SQL, but not for table names. You have to use stringWithFormat for the table names and sqlite3_bind_xxx for the values.
You need to bind a value for each ? in the query. The 2nd parameter to the sqlite3_bind_xxx function is the index number. These are 1-based indexes.
In you 1st query you bind a value to the 1st ? two times. You probably need to change the sqlite3_bind_int call to pass 3 as the index instead of 1.
sqlite3_bind_int(statement, 3, del.tableRowNumber);
One other possible issue is your use of sqlite3_bind_text for the table name. This will put the table name in quotes. As suggested by Rob, you should use a string format to apply the table name but use sqlite3_bind_xxx for actual values you need in your query.

Not inserting rows in sqlite database in iOS

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

ios sqlite3_bind_text step returns null

In the following code everything seems right but the notated lines always return an error code of null no matter what data I feed them. I've researched and changed all the parameters I can think of. The first sqlite3_bind_text line is successful and the next three fail every time. I can't figure it out. Help?
-(void)fillSqliteDb
{
sqlite3 *database;
if (sqlite3_open([[self sqliteFilePath] UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Failed to open database");
}
NSString *createSQL = #"CREATE TABLE IF NOT EXISTS FUNCTIONS (nouns TEXT, verbs TEXT, adverbs TEXT, adjectives TEXT);";
char *errorMsg;
if (sqlite3_exec (database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Error creating table: %s", errorMsg);
}
sqlite3_stmt *stmt;
for (int i=0; i<260; i++) {
NSString * pln = self.pluralNouns[i]; // pre-filled array of 260 words
NSString * vrb = self.verb[i]; // pre-filled array of 260 words
NSString * adv = self.adverb[i]; // pre-filled array of 260 words
NSString * adj = self.adjective[i]; // pre-filled array of 260 words
char *update = "INSERT INTO FUNCTIONS (nouns, verbs, adverbs, adjectives) VALUES (?, ?, ?, ?);";
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [pln UTF8String], -1, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) // Works, word ends up in database
NSLog(#"Error updating table: %s", errorMsg);
sqlite3_bind_text(stmt, 2, [vrb UTF8String], -1, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
NSLog(#"Error updating table: %s", errorMsg);
sqlite3_bind_text(stmt, 3, [adv UTF8String], -1, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
NSLog(#"Error updating table: %s", errorMsg);
sqlite3_bind_text(stmt, 4,[adj UTF8String], -1, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
NSLog(#"Error updating table: %s", errorMsg);
}
}
}
There are several things wrong with this code.
Only call sqlite3_prepare_v2 once. Do it before the for loop.
You need to call sqlite3_bind_xxx once for each variable, all before calling sqlite3_step.
Only call sqlite2_step once per loop. Do this at the end of the loop.
After calling sqlite3_step at the end of the loop, you need to call sqlite3_reset.
After the loop you need to call sqlite3_finalize on the prepared statement.
Since you opened the database connection at the start of the method, you need to close it at the end of the method.
Your use of errorMsg for all of the logs after checking the result of each sqlite3_step call is wrong. errorMsg is only set from the call to sqlite3_exec. To get the error message of the other calls you need to use sqlite3_errmsg.
Updated code:
- (void)fillSqliteDb {
sqlite3 *database;
if (sqlite3_open([[self sqliteFilePath] UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Failed to open database");
}
NSString *createSQL = #"CREATE TABLE IF NOT EXISTS FUNCTIONS (nouns TEXT, verbs TEXT, adverbs TEXT, adjectives TEXT);";
char *errorMsg;
if (sqlite3_exec (database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, #"Error creating table: %s", errorMsg);
}
sqlite3_stmt *stmt;
char *update = "INSERT INTO FUNCTIONS (nouns, verbs, adverbs, adjectives) VALUES (?, ?, ?, ?);";
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
for (int i=0; i<260; i++) {
NSString * pln = self.pluralNouns[i]; // pre-filled array of 260 words
NSString * vrb = self.verb[i]; // pre-filled array of 260 words
NSString * adv = self.adverb[i]; // pre-filled array of 260 words
NSString * adj = self.adjective[i]; // pre-filled array of 260 words
sqlite3_bind_text(stmt, 1, [pln UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 2, [vrb UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 3, [adv UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 4, [adj UTF8String], -1, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
NSLog(#"Error updating table: %s", sqlite3_errmsg(database));
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
}
sqlite3_close(database);
}

Not able to update the column value in the sqlite3

I am new to the iPhone programming and was hoping that someone would be able to help me out with a problem that I've been trying to fix for a few days now. I have created a database and a table. In my program, it contain 5 fields and I am setting two of the fields to zero. And later I am updating these fields to one for a purpose. But the problem is I am not able to set the field value to one. I will paste the code below :
NSString *querySQL = [NSString stringWithFormat: #"UPDATE TODOLIST_03 SET DELETEROW ='1' WHERE TASK=\"%#\"", cellText1];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(TODOLIST_03_DB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
.........
}
}
Can anyone please tell me what is the error in the query?
try following :
const char *sqlQuery="UPDATE TODOLIST_03 SET DELETEROW ='1' WHERE TASK= ?";
if(sqlite3_prepare_v2(database, sqlQuery,-1, &queryStatement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(queryStatement, 1, [cellText UTF8String], -1, NULL);
}
What path did you put database file at? It can not be wrote if you put the database file at the path same as project, you should put it in the sandbox for example NSHomeDocument where it is writeable, and you can modify code like this to track the error:
NSError *err;
if (sqlite3_prepare_v2(TODOLIST_03_DB, query_stmt, -1, &statement, &err) == SQLITE_OK)
{
if(err)
{
// NSLog error or what.
}
}

Resources