Error writing to SQLite DB - iphone

This is my first time using SQL, and I thought I did everything right, but I keep getting the error that my table doesn't exist. To create the table I did:
CREATE TABLE "Users" ("UserID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "UserName" VARCHAR, "Password" VARCHAR)
So I have a table named Users
To write to the table I'm calling this:
- (void) addUser {
if(addStmt == nil) {
const char *sql = "insert into Users(UserName, Password) values (?, ?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [userName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [password UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
userID = sqlite3_last_insert_rowid(database);
//Reset the add statement.
sqlite3_reset(addStmt);
}
When I trigger this, it closes the app and gives me the error
Error while creating add statement. 'no such table: Users'
It took me days to get this far, and I have no clue where to take it from here. What can I do to fix this?
Edit:
This is how I'm importing my DB in my AppDelegate file
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"UserDatabase.sqlite"];
}

I'm pretty sure you get this error because sqlite could not find your sqlite file, so it creates an empty database instead. And in an empty database it would obviously not find your table, hence the error.
So reaching the database file correctly should be your focus. From you code it seems your reading it from the documents directory - but there's no way your db file would get there if you didn't copy it to that directory.
Try adding the actual sqlite file to your bundle. Then, use this code to reach the path of your sqlite file:
databasePath = [[NSBundle mainBundle] pathForResource:#"UserDatabase" ofType:#"sqlite"];
And I believe this would solve your problem. However you should note that if you want to save changes to that db, and I think you want to, you would not to copy the file to the documents directory, because bundled file are read-only. In such case you would search for the sqlite file in the directory path, and if not found (probably first use of app) - copy it to that directory from the bundle.

Related

After adding SQLcipher sqlite3_exec returns SQLITE_NOTADB

I configured SQLCipher as the tutorial in their site... I can compile & Run the project.
But sqlite3_exec returns SQLITE_NOTADB when trying to execute a statement.
Please find code snippet below:
=================
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(success) {
int sql_results = sqlite3_open([dbPath UTF8String], &SQLDB);
const char* key = [#"BIGSecret" UTF8String];
sqlite3_key(SQLDB, key, strlen(key));
if (sql_results == SQLITE_OK) {
NSString *sql;
const char *update_sql;
sql = [NSString stringWithFormat:#"DROP table %#",tablename];
update_sql = [sql cStringUsingEncoding:NSUTF8StringEncoding];
if(sqlite3_exec(SQLDB, update_sql, nil, nil, nil) == SQLITE_OK) {
NSLog(#"Good to go %# dropped",tablename);
}
else {
NSLog(#"Bad Delete Cat SQL: %s -- %d", update_sql,sql_results);
NSLog(#"error code %i", sql_results);
}
Am not able to get the issue, where I went wrong....
Thanks,
Ben
Cross posting from Mailing list:
I noticed in your code that you are only entering the block to
sqlite3_open if the database file exists. Are you by chance trying to
encrypt an existing standard SQLite database using SQLCipher using
this code? If so, calling sqlite3_key will not work that way. You'd
instead want to open the standard SQLite database, attach a new
encrypted database, and then export the data between the two. There
are some more details on this procedure here:
http://sqlcipher.net/sqlcipher-api/#sqlcipher_export
Once you're dealing with an encrypted database you can call
sqlite3_key as the first operation before using it.

how to save data to different table of sqlite database

I am new in sqlite in ios. Thus, what I have to do first and next in order to save data to different tables of database?
I have used Sqlite database in my various application, it works fine for me. You have to follow these steps for inserting the data in the tables of Sqlite database ...
1.First of all you need to create your database... I hope you have created and inserted in your project and also added linked framework libsqlite3.0.dylib and import these in your classes.
2. Replace your insertion method write this code ...
+(void)insertRecord:(NSString *)dbPath record:(NSMutableArray*)dataArray{
#try{
sqlite3_stmt *insertStmnt;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK){
for(int i=0; i<[dataArray count]; i++){
id record=[dataArray objectAtIndex:i];
NSString *insertQuery = [NSString stringWithFormat:#"INSERT INTO Table_Name (\"Column1\",\"Column2\",\"Column3\",\"Column4\",) VALUES('%#','%#','%#','%#')",[[record objectForKey:#"col1"] stringByReplacingOccurrencesOfString:#"'" withString:#"''"],[[record objectForKey:#"col2"] stringByReplacingOccurrencesOfString:#"'" withString:#"''"],[[record objectForKey:#"col3"] stringByReplacingOccurrencesOfString:#"'" withString:#"''"],[[record objectForKey:#"col4"] stringByReplacingOccurrencesOfString:#"'" withString:#"''"]];
const char *sql = [insertQuery cStringUsingEncoding:NSUTF8StringEncoding];
if(sqlite3_prepare_v2(database, sql, -1, &insertStmnt, NULL) == SQLITE_OK){
}else{
}
if(SQLITE_DONE != sqlite3_step(insertStmnt)){
}
}
}
}#catch (NSException *r) {
NSLog(#"UU %#",r);
}
}
Where record is the array of dictionary, which contains the values which you want to insert in the table or values get from the user.
stringByReplacingOccurrencesOfString:
The above method is necessary because if any user enters the data with single cote, then it will lead to your application crash.(you may remove this if you does not take input from the user)
Yes, You can also follow these links for better understanding..
1.http://www.techotopia.com/index.php/IOS_4_iPhone_Database_Implementation_using_SQLite
2.SQLite Tutorial
Hope it will work for you, if you have any query then may reply..
If you're using SQLite then go get FMDB as it will make your life alot easier. All that code above can be shrunk down to a thread safe call something like (off the top of my head, so probably not compile ready).
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdateWithFormat:#"INSERT OR REPLACE INTO table (f1,f2) VALUES (%#, %#);", field1, field2];
DLog(#"insert error: %#", [db lastErrorMessage]);
}];

the select method is adjusting but insert method not working properly

I am working on sqlite database , trying to insert into database but it is giving error "Error while inserting " Database is locked .
I searched some post and also write reset and finalize statement but it is giving same error.
Here is my code
if(addStmt == nil)
{
//const char *sql = "insert into Limittabel (limitAmt) Values(?)";
//const char *sql="INSERT INTO Limittabel (limitAmt, Profileid) VALUES(?, ?)";
const char *sql="insert into Limittabel (limitAmt,Profileid) Values (?,?)";
// Insert into Limittabel (limitAmt,Profileid) Values ($500,1)
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 1, [limitAmt UTF8String], -1, SQLITE_TRANSIENT);
// NSString *str_id_poi = [[NSString alloc] initWithFormat:#"%d", [Profileid integerValue]];
// sqlite3_bind_text(addStmt, 2, [str_id_poi UTF8String], -1, SQLITE_TRANSIENT);
//sqlite3_bind_text(addStmt, 2, [ UTF8String], -1, SQLITE_TRANSIENT);
NSLog(#"***Storing END on Database ***");
if(SQLITE_DONE != sqlite3_step(addStmt))
{
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
} // sqlite3_finalize(addStmt);
else{
//sqlite3_last_insert_rowid;
limitid = sqlite3_last_insert_rowid(database);
NSLog(#"YES THE DATA HAS BEEN WRITTEN SUCCESSFULLY");
}
sqlite3_finalize(addStmt);
}
sqlite3_reset(addStmt);
//sqlite3_finalize(addStmt);
}
If I am not opening the database it is giving Database locked error, if opening database it is giving ' No such Table ' error
Please Help me.
Thanks
I don't understand the "if I am not opening the database it is giving Database locked error" comment, because you simply can't use a database without opening it. It makes no sense to call SQLite functions without first opening database. Maybe I'm not understanding this comment.
But ignoring that for a second, you later say, "if opening database it is giving 'No such table' error": Are you sure you're finding the database correctly? The problem is, if you open database and it's not found, then a blank database will be created. Are you sure this hasn't happened to you? If this may have happened to you, you might want to
Reset the simulator (if you're using simulator) or delete and reinstall the app to make sure any blank databases that sqlite3_open may have created for you will be removed; and
Check to make sure the database exists before you open it or replace your occurrence of sqlite3_open with sqlite3_open_v2 with a third parameter of SQLITE_OPEN_READWRITE and fourth parameter of NULL. See SQLite will not prepare query when accessing database in Xcode
As an aside, you don't mention whether you're opening this from the bundle or Documents, but generally I advise to programmatically copy from bundle to Documents and then open it from there.
If you're doing this on the simulator, I sometimes find it helpful to examine the database used by the simulator from my Mac. Thus, I go to "~/Library/Application Support/iPhone Simulator/5.1/Applications/" (replace the 5.1 with whatever version of your simulator you are using ... if the Library is hidden, unhide it from Terminal with chflags nohidden ~/Library), I then go into the directory for the particular application, go into it's Documents folder, and then open the database in the Mac command line sqlite3 program. You can use that to examine the database and make sure the db is as you expect it.
Just a few thoughts for the "no such table" error.
Here is link for creating, Open , inserting, and retrieve data from the SQLite database . It will help you.
SQLite Datase Create,Insert and Retrieve from the database Click here
jonty to deal with the database its compulsory that first we open the database and then we makes changes in database
and if it giving the error No such table then i recommend you check the existence of table in database i.e. such table created or not.
Try this code,
if(sqlite3_open([YourDatabasePath UTF8String],&db) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"insert into Limittabel (limitAmt,Profileid) Values (?,?)"];
char *errmsg=nil;
if(sqlite3_exec(db, [querySQL UTF8String], NULL, NULL, &errmsg)==SQLITE_OK)
{
NSLog(#"YES THE DATA HAS BEEN WRITTEN SUCCESSFULLY");
}
}
sqlite3_close(db);
If this code doesn't work then there is a problem in your query, check your query again. this code works at my side.

sqlite error 14 [unable to open database file] iphone xcode

Hi i am using database in iphone. After along time, My application gave this error
sqlite error 14 [unable to open database file]
My application is going good but some times it generates the above error.What is the solution?
There is the code:
[lovkid openDatabase:[appDelegate getDBPath]];
NSString *Flag = [NSString stringWithFormat:#"%#", appDelegate.selectimage];
int recId = (int)appDelegate.Id;
NSLog(#"recID = %d",appDelegate.Id);
updateStmt1 = nil;
if(updateStmt1 == nil)
{
const char *sql ="UPDATE 'char' SET `Pic`=? WHERE `id`=?";
if(sqlite3_prepare_v2(database1, sql, -1, &updateStmt1, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database1));
}
sqlite3_bind_text(updateStmt1, 1, [Flag UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int(updateStmt1, 2, recId);
if(SQLITE_DONE != sqlite3_step(updateStmt1))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database1));
else
NSLog(#"no error");
sqlite3_reset(updateStmt1);
sqlite3_finalize(updateStmt1);
...
well u need to try out my answer from the post
and make sure u write the two functions (of the post ) in ur application delgate that way ur app will open DB once
Let me Know if it worked
Cheers :)
The SQLite error 14 can be solved by changing the settings in the directory where the database file is stored.

sqlite delete problem on iPhone

In my iPhone app, I'm trying to delete a row from an SQLite database. After the delete statement is executed the row seems to be deleted correctly, but after I restart the application the row is still there.
I'm using the code blow to delete the record. Any idea what could be the problem?
NSString *deleteSQL = [NSString stringWithFormat:#"DELETE FROM table1 WHERE actId=%d", actId];
char *errorMsg;
if (database == nil) {
NSLog(#"ERROR db not initialized but trying to delete record!!!");
}else{
if (sqlite3_exec(database, [deleteSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK){
NSAssert1(0, #"Error updating tables: %s", errorMsg);
sqlite3_free(errorMsg);
return NO;
}
}
NSLog([NSString stringWithFormat:#"DELETE Successful"]);
I've solved this problem. Although I don't understand exactly all the details. The problem was the in my 'loading code' I forgot to call sqlite3_finalize for the statements. Not sure why but this influenced somehow future inserts and deletes. Adding sqlite3_finalize to the data loading method solved the problem.