iOS- SQLITE_MISUSE error (code 21) - ios

I try Insert an array of objects into my database , all of them inserted successfully except last one , It give me this error
here is my code I use to insert into database
- (int)insertWithQuery:(NSString *)query {
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
const char *insert_stmt = [query UTF8String];
if(sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL)!= SQLITE_OK){
NSLog(#"the error occurred here is %s ",sqlite3_errmsg(database));
return DATABASE_FAILED;
}
int res = sqlite3_step(statement);
if (res == SQLITE_DONE) {
return DATABASE_SUCCESS;
} else if (res == SQLITE_CONSTRAINT) {
return DATABASE_ALREADY_EXISTS;
} else {
return DATABASE_FAILED;
}
sqlite3_finalize(statement);
sqlite3_close(database);
} else {
return DATABASE_FAILED;
}
}
The error Printed to me is
near "3": syntax error
my Passed query is look like
INSERT INTO report (report_id, student_id, report_title, report_body, from_date, to_date, timestamp) VALUES ("217", "1", "", "<h3>Hazem Taha Ghareeb <small>report</small></h3>From: <p>2014-06-17 </p> To: <p>2014-06-24 </p><table><thead><th>Exam</th><th>Date</th><th>Result</th></thead><tbody><tr><td>Java </td><td>2014-06-18 </td><td>138 </td></tr></tbody></table><h3>Absence</h3><table><thead><th>Date</th></thead><tbody><tr><td>2014-06-17 </td></tr><tr><td>2014-06-22 </td></tr><tr><td>2014-06-24 </td></tr></tbody></table></body></html>", "2014-06-17", "2014-06-24", "2014-06-24 12:23:58")
The one have problem is
INSERT INTO report (report_id, student_id, report_title, report_body, from_date, to_date, timestamp) VALUES ("631", "1", "C class report4", "<h3>Hazem Taha <small>report</small></h3>From: <p>30-01-2015 </p> To: <p>30-01-2015 </p><table><thead><th>Exam</th><th>Date</th><th>Result</th></thead><tbody><tr><td colspan="3"> No exams records. </td></tr></tbody></table><h3>Absence</h3><table><thead><th>Date</th></thead><tbody><tr><td> No absence records. </td></tr></tbody></table></body></html>", "2015-01-30", "2015-01-30", "2015-01-29 08:43:21”)
Any one know can help me

The main issue is you have " in your query parameters. You need to escape them with \".
But I would like to suggest using sqlite3_bind_xxx methods for binding parameters to your query rather than specifying them in the query statement.
You can read more about it here : SQLite3 Reference
If you open a database connection you should close it. In your code you are returning from many places, so database connection won't be closed properly, it'll cause database locking and other issues.
- (int)insertWithQuery:(NSString *)query
{
int status = DATABASE_FAILED;
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
const char *insert_stmt = [query UTF8String];
if(sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL)!= SQLITE_OK)
{
NSLog(#"the error occurred here is %s ",sqlite3_errmsg(database));
status = DATABASE_FAILED;
}
else
{
int res = sqlite3_step(statement);
if (res == SQLITE_DONE)
{
status = DATABASE_SUCCESS;
}
else if (res == SQLITE_CONSTRAINT)
{
status = DATABASE_ALREADY_EXISTS;
}
else
{
status = DATABASE_FAILED;
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}

If you will look on "2015-01-29 08:43:21”, you will notice that you have an incorrect quote ” which will cause the problem.
So right query will be
INSERT INTO report (report_id, student_id, report_title, report_body, from_date, to_date, timestamp) VALUES ("631", "1", "C class report4", "<h3>Hazem Taha <small>report</small></h3>From: <p>30-01-2015 </p> To: <p>30-01-2015 </p><table><thead><th>Exam</th><th>Date</th><th>Result</th></thead><tbody><tr><td colspan="3"> No exams records. </td></tr></tbody></table><h3>Absence</h3><table><thead><th>Date</th></thead><tbody><tr><td> No absence records. </td></tr></tbody></table></body></html>", "2015-01-30", "2015-01-30", "2015-01-29 08:43:21")

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

How to execute two insert query in single statement in sqlite3 [duplicate]

This question already has an answer here:
Delete multiple tables from a single query by separating from semicolon
(1 answer)
Closed 7 years ago.
I am trying to insert the values in two different tables in a single statement, first insert query in working second query is not working.
sqlite3_stmt * statement= NULL;
const char *dbpath =[databasePath UTF8String];
if (sqlite3_open(dbpath, &mySqliteDB)== SQLITE_OK)
{
for (PostObject * post in in_PostObject)
{
**query**
NSString * postSql =[NSString stringWithFormat:#"insert or ignore into %#_post (postid,data,active) values (\"%#\",?,\"%d\");",tblPrefix,post.post_ID,post.active];
/*Appending First query with second query*/
NSString * insertSQl =[postSql stringByAppendingString:[NSString stringWithFormat:#" insert into %#_forumuser (uid,utype,name) values (1,'parent','javid');",tblPrefix]];
NSLog(#"%#",insertSQl);
const char * insert_stmt=[insertSQl UTF8String];
sqlite3_prepare_v2(mySqliteDB, insert_stmt, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [post.jsonData UTF8String], -1, SQLITE_TRANSIENT);
if (sqlite3_step(statement)==SQLITE_DONE)
{
success =TRUE;
}
else
{
NSLog(#"DB Error: %s", sqlite3_errmsg(mySqliteDB));
}
}
}
sqlite3_finalize(statement);
sqlite3_close(mySqliteDB);
You need to check the return code from the sqlite3_prepare_v2 to make sure there aren't any problems.
Also you shouldn't need to open and close the database for each statement you want to execute, there you could process them as 2 statements
if(sqlite3_prepare_v2(mySqliteDB, insert_stmt,-1, &statement, NULL) != SQLITE_OK) {
NSLog(#"%s Prepare failure '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
}

SQL ERROR: near "m": syntax error. In Statement: insert into table? [duplicate]

I have one question.
I'm getting information from JSON and he returns me invalid character.
JSON give me this: "27/"" when I need this: 27". I understand this is a encode for special characters but when I use the value on NSString to make an Insert in a SQLite table, I can't use 27/" cause the insert format is this: INSERT INTO FORMATOS (ID, NOMBRE) VALUES ("17", "27"").
What method I need to Insert information correctly in the SQLlite?
for (int i = 0; i<idFormato.count; i++) {
NSString *idStr = [idFormato objectAtIndex:i];
NSString *nameStr = [nameFormato objectAtIndex:i];
insertSQL = [NSString stringWithFormat:#"INSERT INTO FORMATOS (ID, NOMBRE) VALUES (\"%#\", \"%#\")", idStr, nameStr];
//Char constant with the query encoded un UTF
const char *insert_stmt = [insertSQL UTF8String];
//Execute query
sqlite3_prepare_v2(dieneDB, insert_stmt, -1, &statement, NULL);
//Check if Statment is dne correctly
if(sqlite3_step(statement) == SQLITE_DONE){
NSLog(#"Guardado Formatos correctamente");
}
The JSON:
[
{"ID_FORMATO_INT":"17","NOMBRE_FORMATO_STR":"2,5\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:17:55","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"18","NOMBRE_FORMATO_STR":"4\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:18:20","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"19","NOMBRE_FORMATO_STR":"4,7\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:20:07","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"20","NOMBRE_FORMATO_STR":"5,5\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:20:15","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"21","NOMBRE_FORMATO_STR":"9,7\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:20:42","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"22","NOMBRE_FORMATO_STR":"7,9\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:21:04","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"23","NOMBRE_FORMATO_STR":"11\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:22:40","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"24","NOMBRE_FORMATO_STR":"13\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:22:44","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"25","NOMBRE_FORMATO_STR":"15\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:22:49","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"26","NOMBRE_FORMATO_STR":"21,5\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:23:11","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null},{"ID_FORMATO_INT":"27","NOMBRE_FORMATO_STR":"27\"","ID_USUARIO_ALTA_INT":"3","FECHA_ALTA_FORMATO_DAT":"2014-09-18 07:23:14","ID_USUARIO_MOD_INT":null,"FECHA_MOD_FORMATO_DAT":null}
]
The issue is that you're building your SQL withstringWithFormat. That is a practice that is susceptible to this sort of problem. Instead, use ? placeholders in your SQL and then use sqlite3_bind_text to bind values to the ? placeholders. See the sqlite3_bind_text() help for more information.
For example, you might:
const char *insert_stmt = "INSERT INTO FORMATOS (ID, NOMBRE) VALUES (?, ?)";
if (sqlite3_prepare_v2(dieneDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK) { // prepare SQL
NSLog(#"prepare error: %s", sqlite3_errmsg(dieneDB));
} else {
if (sqlite3_bind_text(statement, 1, idStr, -1, NULL) != SQLITE_OK) { // bind 1
NSLog(#"bind idStr error: %s", sqlite3_errmsg(dieneDB));
} else if (sqlite3_bind_text(statement, 2, nameStr, -1, NULL) != SQLITE_OK) { // bind 2
NSLog(#"bind nameStr error: %s", sqlite3_errmsg(dieneDB));
} else if (sqlite3_step(statement) != SQLITE_DONE) { // perform SQL
NSLog(#"step error: %s", sqlite3_errmsg(dieneDB));
} else {
NSLog(#"Guardado Formatos correctamente");
}
sqlite3_finalize(statement);
}
I just typed this in, so please forgive any typos, but hopefully it illustrates the idea.
Note, I also (a) check all of these return codes; (b) log the error if any; and (c) finalize the statement when done.

Drop table sqlite issue

I've been able to drop and reload tables using this same code structure, but running into an issue for this table. Essentially what my code intends to do is allow the user to delete their custom selections and restore defaults. Any insight on why I'm unable to drop table is appreciated.
EDIT: the issue was that the inital table to drop did not exist. I ended up using sqlite3_errmsg to figure that out.
- (void) dropReloadFoodlistTable{
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_profileDB) == SQLITE_OK)
{
NSString *querySQL = #"DROP TABLE FOODLIST";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_profileDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"SQL Statement complete");
}
sqlite3_finalize(statement);
}
char *errMsg2;
const char *sql_stmt2 =
"CREATE TABLE IF NOT EXISTS FOODLIST (ID INTEGER PRIMARY KEY AUTOINCREMENT, CARB STRING, PROTEIN STRING, FAT STRING, FRUIT STRING, VEG STRING)";
if (sqlite3_exec(_profileDB, sql_stmt2, NULL, NULL, &errMsg2) != SQLITE_OK)
{
NSLog( #"Failed to create FOODLIST table");
}
sqlite3_close(_profileDB);
}
[self initialDataLoadFoodList];
}
This code does not execute the DROP TABLE statement.
To execute a prepared statement, you must call sqlite3_step.
You prepare the statement, but never use sqlite3_step() to actually execute it.
(reference)

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