how to insert a db in sqlite3? shows error - objective-c

I'm trying to insert my data into db.db created successfully but data not insert into the database.but the data successfully goes to insertsql after that showing error.pls check my code
-(void)insertDB
{
NSString *dname=[[NSString alloc]init];
dname=[delegate.Name objectAtIndex:0];
sqlite3_stmt *statement;
const char *dbpath=[delegate.databasepath UTF8String];
if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK)
{
NSString *insertSQL=[NSString stringWithFormat:#"INSERT INTO STABLE (NAME) VALUES (\"%#\")",dname];
//insert sql is ok,after that they shows error
const char *insert_stmt=[insertSQL UTF8String];
NSLog(#"const char%#",insert_stmt);
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement,NULL);
if (sqlite3_step(statement)==SQLITE_DONE)
{
NSLog(#"saved");
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"data" message:#"saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[self counting];
}
else
{
NSLog(#"Failed to add new favourites");
NSLog(#"Failed to update row %s", sqlite3_errmsg(contactDB));
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
[self loadmusic];
}

You say that the error message returned is:
Failed to update row no such table: STABLE
And, well, the problem is exactly that: there is no table called STABLE. You've clearly managed to connect to a database but there is no table there with the name that you expect.
The real question is how and when did you create the table? Chances are the database you're connected to is not the one you think is being used.

Related

Database is locked while updating data in background

I'm working on an application where I've to use sqlite and there are lots of data. I want to load data from "residents_status" column of a table named "tblResident". it is taking too much time to load data of that column (residents_status) more than 8 seconds and other data takes just a second. During the period of fetching the data from "residents_status" column, if I press a button its give me 'query error'
in else part but if I click button after 8 seconds than it is working fine.
Here is my code:
if(sqlite3_exec(database, insert_stmt, NULL, NULL, &error)==SQLITE_OK)
{
NSLog(#"succeddd.....");
IsValidate = true;
if([self checkNetConnection])
{
[self UpdateServerWith_LocalDB];
NSString *Key= [DefaultsValues getStringValueFromUserDefaults_ForKey: #"Key"];
if([[DefaultsValues getStringValueFromUserDefaults_ForKey: #"LastAuthenticationStatus"] isEqualToString:#"false"]){
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:nil message:#"Your Access is Restrcited,Please contact us" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
}
else{
NSLog(#"query error");
ErrorMsg = [NSString stringWithFormat:#"%s", error ];
IsValidate = false;
}

sqlite_prepare_v2 does not return SQLITE_OK

I have been trying to save highscore into database and have been failing for past week, and I have no clue why it is not working. I keep receiving "Problem with prepare statement" and refuses to insert info into database. I have checked with database manager to make sure there is not a typo with sql statement, and when query is run on manager, it works fine - it's just the iphone that's giving me the problem. If anyone could please look over quickly and see something wrong with it and could let me know, I would really appreciate it!
- (NSMutableArray *) saveLocal {
NSLog(#"save local database");
#try {
[self checkDB];
sqlite3_stmt *sqlStatement2;
NSString *sqlS = [NSString stringWithFormat:#"INSERT INTO localHighscore (difficulty, score, uname, puzzles, multiplier, oneshots, hints) VALUES (%i,%i,\"%#\",%i,%i,%i,%i)",[[MySingleton sharedMySingleton] goDifficulty],[[MySingleton sharedMySingleton] goScore],_player, [[MySingleton sharedMySingleton] goPuzzles], [[MySingleton sharedMySingleton] goMultiplier], [[MySingleton sharedMySingleton] goOneshots], [[MySingleton sharedMySingleton] goHints]];
NSLog(#"%#",sqlS);
const char *sql = [sqlS UTF8String];
if(sqlite3_prepare_v2(localHighscore, sql, -1, &sqlStatement2, NULL) == SQLITE_OK)
{
sqlite3_step(sqlStatement2);
sqlite3_reset(sqlStatement2);
sqlite3_finalize(sqlStatement2);
NSLog(#"save complete");
} else {
NSLog(#"Problem with prepare statement");
}
sqlite3_close(localHighscore);
}#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}#finally{
NSLog(#"DB Loaded!");
}
}
and here is checkDB method which checks if database exists and creates one if it does not
- (void)checkDB {
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"localHighscore.sqlite"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
NSLog(#"file was not found");
if (sqlite3_open(dbpath, &localHighscore) == SQLITE_OK)
{
NSLog(#"db open");
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS localHighscore(pk INTEGER PRIMARY KEY AUTOINCREMENT, difficulty TINYINT, score MEDIUMINT, uname VARCHAR(255), puzzles TINYINT, multiplier TINYINT, oneshots TINYINT, hints TINYINT)";
if (sqlite3_exec(localHighscore, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table");
}
sqlite3_close(localHighscore);
} else {
NSLog(#"Failed to open/create database");
}
}
[filemgr release];
}
Thanks in advance for the help!
A couple of thoughts:
You don't appear to call sqlite3_open before trying to use the database.
Whenever you get an error, you should look at sqlite3_errmsg, e.g.
if (sqlite3_exec(localHighscore, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table: %s", sqlite3_errmsg(localHighscore));
}
Probably unrelated to your problem, but you should generally not build a SQL statement using stringWithFormat (at least if you have any text fields). Use ? placeholders in your SQL and then use sqlite3_bind_xxx functions.
const char *sql = "INSERT INTO localHighscore (difficulty, score, uname, puzzles, multiplier, oneshots, hints) VALUES (?,?,?,?,?,?,?)";
if(sqlite3_prepare_v2(localHighscore, sql, -1, &sqlStatement2, NULL) == SQLITE_OK)
{
if (sqlite3_bind_int(sqlStatement2, 1, [[MySingleton sharedMySingleton] goDifficulty]) != SQLITE_OK) {
NSLog(#"bind 1 failed: %s", sqlite3_errmsg(localHighscore));
}
if (sqlite3_bind_int(sqlStatement2, 2, [[MySingleton sharedMySingleton] goScore]) != SQLITE_OK) {
NSLog(#"bind 2 failed: %s", sqlite3_errmsg(localHighscore));
}
if (sqlite3_bind_text(sqlStatement2, 3, [_player UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(#"bind 3 failed: %s", sqlite3_errmsg(localHighscore));
}
// repeat this bind process for each variable
if (sqlite3_step(sqlStatement2) != SQLITE_DONE) {
NSLog(#"step failed: %s", sqlite3_errmsg(localHighscore));
}
// reset not needed (doesn't hurt, but not needed unless you're going to re-use it
// sqlite3_reset(sqlStatement2);
sqlite3_finalize(sqlStatement2);
NSLog(#"save complete");
} else {
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(localHighscore));
}
sqlite3_close(localHighscore);
If you find this syntax unwieldy, then maybe consider using FMDB, which simplifies your SQL interaction. But be very wary of stringWithFormat with SQL (if the inserted string had a quotation mark, the sqlite3_prepare will fail, theoretically, your app is exposed to SQL injection attacks, etc.).
As an aside, you should not [filemgr release], as you don't own it.
I saw that the "sqlite3_prepare_v2 ()" function, returns a 'generic error' (error code = 1) when the SQL statement contains conditions like "booleanfield=false" instead of "booleanfield=0". The same SQL statement executed in the SQL box of SQLiteStudio program gives good results using indifferently the first or the second form of the comparison.

Make a Loop Array or Bulk to Insert Dictionary with Multiple Values from a parsed Json string into a SQLite database with FMDB iOS. Objective C

I have a Parsed Json string in which I would like to loop the values and insert them into my FMDB Sqlite database. I can only put one record at a time in the database. i want to put all my records in the sqlite database.
I know I have to make up some sort of loop for this.
I want to take the parsed json which has multiple values below and insert it into my column named unitofMeasure and Name.
So I want to create a loop to insert multiple id's and multiple names into the unitOfMeasureID column and Name column in my database.
Currently I can only insert i record at a time.
UnitOfMeasureID To Use: 1
Name: kph
UnitOfMeasureID To Use: 2
Name: kpm
UnitOfMeasureID To Use: 3
Name: kpm
for (defineJsonDataLookUp in self.jsonLookup)
{
NSNumber* UnitOfMeasureID = [defineJsonDataLookUp objectForKey:#"unitOfMeasureID"];
NSLog(#"UnitOfMeasureID To Use: %#", UnitOfMeasureID);
NSNumber* Factor = [defineJsonDataLookUp objectForKey:#"Factor"];
NSLog(#"Factor To Use: %#", Factor);
NSArray* Name = [defineJsonDataLookUp objectForKey:#"Name"]; //for actual json response
NSLog(#"Name: %#", Name); //3
NSNumber* ParentID = [defineJsonDataLookUp objectForKey:#"ParentID"];
NSLog(#"ParentID: %#", ParentID);
}
if ([strResult isEqualToString:#"[]"])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet Connection!" message:#" Please connect to the Internet" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
else
{
for (defineJsonDataLookUp in self.jsonLookup)
{
NSNumber* UnitOfMeasureID = [defineJsonDataLookUp objectForKey:#"unitOfMeasureID"];
NSLog(#"UnitOfMeasureID To Use: %#", UnitOfMeasureID);
NSNumber* Factor = [defineJsonDataLookUp objectForKey:#"Factor"];
NSLog(#"Factor To Use: %#", Factor);
NSArray* Name = [defineJsonDataLookUp objectForKey:#"Name"]; //for actual json response
NSLog(#"Name: %#", Name); //3
NSNumber* ParentID = [defineJsonDataLookUp objectForKey:#"ParentID"];
NSLog(#"ParentID: %#", ParentID);
FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
[db open];
[db executeUpdate:[NSString stringWithFormat:#"delete from unitofmeasure"]];
[db executeUpdate:#"INSERT INTO unitofmeasure (unitOfMeasureID,Factor,Name,ParentID) VALUES (?,?,?,?)",UnitOfMeasureID,Factor,Name,ParentID];
// [db executeUpdate:#"INSERT INTO unitofmeasure (unitOfMeasureID,Name) VALUES (?,?);",
// [self.defineJsonDataLookUp objectForKey:#"unitOfMeasureID"],[self.defineJsonDataLookUp objectForKey:#"Name"], nil];
FMResultSet *results = [db executeQuery:#"select * from unitofmeasure"];
while([results next]) {
NSString *Name = [results stringForColumn:#"Name"];
NSInteger ParentID = [results intForColumn:#"ParentID"];
NSLog(#"UdadfdadfddfFuckingser: %# - %d",Name, ParentID);
}
[db close];
}
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
}
}
My SQlite Database looks like this and I want to insert all the records from my dictionary UnitOfMeasureID: 1, Name:kph, UnitOfMeasureID: 2, Name: kpm, UnitOfMeasureID: 3, Name: kpm
Regards
You don't give much to go on. What's the structure of the database? What are the primary keys? Which are unique keys? What does the JSON data look like? Is it valid? Are you trying to insert what you think you are?
But, as general advice, you're ignoring error return codes.
[db executeUpdate:#"INSERT INTO unitofmeasure"];
Should be:
if(! [db executeUpdate:#"INSERT INTO unitofmeasure"]) {
// handle error
}
From the documentation:
Executing updates returns a single value, a BOOL. A return value of
YES means the update was successfully executed, and a return value of
NO means that some error was encountered. You may invoke the
-lastErrorMessage and -lastErrorCode methods to retrieve more information
Finally, I assume this is a copy-and-paste error:
[db executeUpdate:[NSString stringWithFormat:#"delete from unitofmeasure"]];
[db executeUpdate:#"INSERT INTO unitofmeasure
The first line deletes all rows in the table. The second inserts a single row.

Xcode write the data base but still empty

First of all I am from spain so sorry about my grammar. I am writing some data to a sqlite data base, here is my code:
I have allredy checked that the data base, table and column names are ok, when I change anything I get errors, so the code its working properly.
#try {
NSFileManager *fileMgr=[NSFileManager defaultManager];
NSString *dbPath=[self database];
BOOL succes=[fileMgr fileExistsAtPath:dbPath];
if(!succes)
{
NSLog(#"Cannot locate database '%#'.",dbPath);
}
if (!(sqlite3_open([dbPath UTF8String], &dbcapturas)==SQLITE_OK)) {
NSLog(#"An error has occured: %#",sqlite3_errmsg(dbcapturas));
}
//sqlite3_stmt *sqlStatement;
NSString *asd=numero.text;
NSString *insertStatement=[NSString stringWithFormat:#"INSERT INTO captura(key,tecnico, fecha,provincia,municipio,latitud,longitud,altura,familia,especie,numero,comentario)Values(\"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\", \"%#\")",asd,tecnico,fechaHora,tecnico,municipio,latitud,longitud,altura,tecnico,animal,asd,coment];
char *error;
if((sqlite3_exec(dbcapturas, [insertStatement UTF8String], NULL, NULL, &error))==SQLITE_OK)
{
NSLog(#"Person inserted.");
}
else
{
NSLog(#"Error: %s", error);
}
} #catch (NSException *exception) {
NSLog(#"fail");
}
#finally {
NSLog(#"cerrada");
sqlite3_close(dbcapturas);
}
the first time I click on the save button I get:
2012-07-04 12:17:45.644 adasdasd[1783:f803] Person inserted.
and the second time I get :
2012-07-04 12:29:18.959 adasdasd[1840:f803] Error: column key is not
unique
So my code should be ok but when I open the database with the firefox add-on its totally empty, any idea?
Edit: I now call
-(NSString *)database{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"capturas.sqlite"];
}
but now I get a error saying me: no such table: capturas
I have a table capturas in my db 100% sure
When setting up your table, the column key is probably indexed or defined to be unique or auto-incrementing. When you do the insert, you pass a specific key, namely whatever is in the variable asd. If you try that the second time, you will get the sqlite error because the column key has to be unique. If it is auto increment, just leave it out and it will be filled automatically.
The first entry should be in the database if you closed it correctly. Make sure you are checking the correct copy of the database with Firefox (test by inserting a dummy record in your app delegate, for example).

Cannot select from sqlite3 database

I have some problem with reading from sqlite3 database.
-(void) readMessengesFromDatabase {
sqlite3 *database;
messenges = [[NSMutableArray alloc] init];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(#"Connection OK");
const char *sqlStatement = "select * from MessagesData";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) NSLog(#"connect to table OK"); else NSLog(#"connect to table FALSE");
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { //не проходит условие
NSLog(#"Connection to table OK");
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSLog(#"Read rows OK");
NSString *dbMessageID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *dbMessageText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *dbMessageDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *dbMediaOrNot = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
Message *messege = [[Message alloc] initWithName:dbMessageText messageID:dbMessageID messageDate:dbMessageDate mediaOrNot:dbMediaOrNot];
[messenges addObject:messege];
[messege release];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
My first NSLog shows me what connection to database is ok. But next step "select * from MessagesData" and if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) NSLog(#"connect to table OK"); else NSLog(#"connect to table FALSE"); shows me "connect to table FALSE". Tried select from my database's table whith Terminal and got error "unable to open database file" . Where is my mistake? I don't see any problems in my code...
If you print the error code returned by sqlite3_prepare_v2 it will be a lot easier to diagnose the problem. The numeric values can be found on this page.
int errorCode = sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
if(errorCode != SQLITE_OK) {
NSLog(#"Connect to table failed: %d", errorCode);
}
However, if you cannot even select from the database in the sqlite3 command line tool, I suggest you check that the file exists, is readable and in the correct format.
Try to reproduce the error in your simulator (failing that, copy the database file to your computer e.g. using Organizer). Try to run the query using sqlite3 (I know you did try that, but make sure you are checking the following).
If you are getting the message Error: file is encrypted or is not a database, it means that the database file is corrupt. If you get Error: no such table:, it means your database does not exist, is empty, or simply hasn't got the table. If you get (as in your question): Error: unable to open database (you get this during the opening of sqlite, not when performing the query), it means that sqlite cannot read the file (for example permissions).
well i m guessing ur Database is not being able to connect.
Try My Answer From Here...
I mentioned few things here and i believe u ll be just Fine
Let me know it worked
write a code for check that table exist or not. and before u execute the query select u should check that create table if not exists ....
NSLog(#"Connection OK");
sqlite3_exec(database,"CREATE TABLE IF NOT EXISTS MessagesData (ID INTEGER PRIMARY KEY AUTOINCREMENT ,"
"FirstName TEXT,LastName TEXT"));
const char *sqlStatement = "select * from MessagesData";
If it work please like it