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)
Related
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));
}
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")
Im super new to ios (Objective-C) and sql and Im following a tutorial of sqlite (specifically sqlite3) found here: http://www.tutorialspoint.com/ios/ios_sqlite_database.htm
and i implemented everything correctly. The problem is that if I try to enter information with the same reg id (The primary key which is used to find elements in the database), it complains about the key not being unique.
- (BOOL) saveData:(NSString*)registerNumber name:(NSString*)name
department:(NSString*)department year:(NSString*)year;
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *insertSQL =
[NSString stringWithFormat:#"insert into studentsDetail (regno,name, department, year) values (\"%d\",\"%#\", \"%#\", \"%#\")",[registerNumber integerValue], name, department, year];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
int s = sqlite3_step(statement);
const char *errmsg = sqlite3_errmsg(database);
if (s == SQLITE_DONE)
{
sqlite3_reset(statement);
return YES;
}
else {
sqlite3_reset(statement);
return NO;
}
}
return NO;
}
How do I go about making the saveData: action actually update the entry inside the database instead of just being rejected?
Thanks!
"I want to extend it so that if I try to enter an existing reg id, it
will overwrite the remaining properties with the new ones"
If this is what you are trying to accomplish then you should not be using an INSERT statement. The purpose of the primary key is to protect the database from duplicate rows with the same primary key. When you look at it that way, the rejection is appropriate.
What you really want is to use INSERT OR REPLACE
If you're a beginner to both sql and objective c, I'd recommend a sqlite wrapper I created that is aimed at beginners: TankDB
Edit:
Code example:
INSERT OR REPLACE INTO studentsDetail (regno,name, department, year) values (\"%d\",\"%#\", \"%#\", \"%#\")"
Refer to this question to make sure that you don't actually mean to use 'UPSERT'. Beware that INSERT OR REPLACE does not update the existing row with the new information. It will completely delete the existing row and replace it.
Edit2: Open, prepare, step, finalize, close
const char *dbpath = [_databasePath UTF8String];
if(sqlite3_open(dbpath, &_database) == SQLITE_OK) {
const char *command = [query UTF8String];
// Perform the query
if (sqlite3_prepare_v2(_database, command, -1, &selectstmt, NULL) == SQLITE_OK) {
// For each row returned
while (sqlite3_step(selectstmt) == SQLITE_ROW) {
// Do stuff
}
}
sqlite3_finalize(selectstmt);
}
sqlite3_close (_database);
I am creating an app and using sqlite 3 for storing data.
Here is my code I am executing to fetch data
sqlite3_stmt *statement;
NSString *querySQL = [NSString stringWithFormat: #"SELECT ID, HolderName, AccountNumber, BankName, Location FROM Accounts WHERE UserID='%#'",userID];
if(![name isEqualToString:#""])
{
querySQL = [NSString stringWithFormat: #"SELECT ID, HolderName, AccountNumber, BankName, Location FROM Accounts WHERE UserID='%#' and HolderName='%#'",userID, name];
}
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
....
}
}
What is happening here, if name is empty then query(only with one condition in where clause) runs properly and fetches proper data but its giving error : library routine called out of sequence if name is not empty and query contains two conditions in where clause.
I am not sure what is wrong with it, I have searched a lot but found that query runs perfect with multiple conditions.
Please suggest me what should I do here.
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.
}
}