What do I need after an INSERT statement? - sql

I have an INSERT statement, followed by a SQLITE3_EXEC, followed by a SELECT statement and another SQLITE3_EXEC. I'm getting an SQLERROR 21 (SQLITE_MISUSE) on the EXEC for the SELECT statement.
Am I missing something between the two EXECs? like a COMMIT, or?
Is it possible that the 21 refers to trying to insert a record that already exists?
NSString *insertCommand = [NSString stringWithFormat:#"INSERT INTO CardData (CARD_ID, CARD_NAME, CODE_VAL) VALUES ('/%#', '/%#', '/%#')",
symbol.data, #"Test Card", symbol.typeName];
sqlite3_exec(db, [insertCommand UTF8String], NULL, NULL, &errmsg);
if(errmsg != NULL)
NSLog(#"insert error: /%#", &errmsg); // DEBUGGING ONLY!
// now, pull it back out of the d/b and display the data
const char *sqlStatement = #"select CARD_ID, CARD_NAME, CODE_VAL from CardData";
sqlite3_stmt *compiledStatement;
int err = sqlite3_prepare_v2(db, [sqlStatement UTF8String], -1, &compiledStatement, NULL); // Setup the SQL Statement and compile it for faster access
if(err != SQLITE_OK)
NSLog(#"prepare error: /%#", err);
else {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
resultText.text = [NSString stringWithFormat:#"\nDatabase: \n%# \n%# \n%#", resultText.text,
[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)],
[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)],
[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)]];
}
sqlite3_finalize(compiledStatement); // release it...
sqlite3_close(db);
}

According to documentation, (1.4 Error Codes->SQLITE_MISUSE) it says that you can get this error if you try to access closed database or calling sqlite_exec with same database pointer from two different threads. Just check out for these 2 possibilities in your case.
Hope it helps.

I have decided to use FMDB... thanks everybody for the suggestions, I appreciate your time.

Related

Objective c : How to fetch data from sqlite table as per primary key?

Say I am having 1 table called ABC with fields ABCid,ABCname,ABCImagePath,ABCSequence. Now this table contains more than 40 rows inside the same.
Now I have an array of numbers say 1,4,5,7,8 and I want to compare these numbers with ABCid and fetch all the data from table ABC as per these IDs.
+ (void) getSelectedData : (int)ABCId
{
NSString *dbPath = [self getDBPath];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *query =[NSString stringWithFormat:#"select * from [ABC] where ABCId=%d",ABCId];
const char *sql = [query cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
[self getInitialDataToDisplay:dbPath];
ABC *DataObj = [[ABC alloc] initWithPrimaryKey:ABCId];
DataObj.ABCName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
ABCImagePath = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)];
DataObj.ABCSequence = sqlite3_column_int(selectstmt,8);
[appDelegate.arrGetData addObject:DataObj]; }
else
{
NSAssert1(0,#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
NSLog(#"%d",[appDelegate.DataArrayTrans count]);
}
else
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}
But app gets crashed in the if condition. Also note that I use below lines from the pageController to call the above function from ABC Object file.
for(int i=0;i<[arrRId count];i++)
{
[ABC getSelectedData:[[arrRId objectAtIndex:i]integerValue]];
[arr576576 addObject:[appDelegate.arrGetData valueForKey:#"ABCId"]];
}
Please guide me where I am making mistake. Thank you.
your query should be like this select * from ABC where ABCId IN (1,4,5,7,8)
that's it.

inserting into SQLite

I have a problem with the inserting and retrieving code
There is no run time error but inserting data is not working and the retrieving code only retrieves the last record from the DB.
Is it better to use NSString or NSMutableString?
NSLog(#"test");
NSString *sql1 = [NSString stringWithFormat:#"INSERT INTO User Values (2,'%#','','F','123','','','','','A','B','123','123',2)",name.text];
char *err;
sqlite3_exec(database, [sql1 UTF8String], NULL, NULL, &err)!= SQLITE_OK ;
const char *sql = "select * from User";
sqlite3_stmt *searchStatement;
if (sqlite3_prepare_v2(database, sql, -1, &searchStatement, NULL) == SQLITE_OK)
{
while (sqlite3_step(searchStatement) == SQLITE_ROW)
{
char * try = (char*)sqlite3_column_text(searchStatement, 1);
if (try){
item = [NSMutableString stringWithUTF8String:try];
}
else{
item = #"";
}
The issue seems to be in your retrieval code. The sqlite3_column_type methods use zero-based indexing, but it looks like you are starting from position 1. Thus each time you step through, you aren't pulling out the information you need. I'm not sure why you are getting the last item, but try going from position 0 and see if that helps.

Can't get data - sqlite3

I use sqlite for my simple iOS app. The problem is that I can't get the result from the query. I will skip the code which is responsible for opening the database. It works.
NSString *query = #"SELECT * FROM tickets LIMIT 0,1";
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
{
NSString *strResult = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
NSLog(#"%#", strResult);
sqlite3_finalize(statement);
}
Here the app crash with a message:
NSInvalidArgumentException', reason: '*** +[NSString stringWithUTF8String:]: NULL cString'
I'm 100% sure that the query
SELECT * FROM tickets LIMIT 0,1
return result which is not NULL. I have tested the query above with sqlite client and it works fine.
What is wrong here ?
You didn't evaluate your statement. You should use:
int sqlite3_step(sqlite3_stmt*);
after sqlite3_prepare_v2.

EXC_BAD_ACCESS SQL DATABASE

I got this exc_bad_access problem in AppDelegate.m
What I did and want is to have multiple sql query. To avoid complexity, I did two blocks (it will have more) and both are querying different table from sql.
-(void)readDataFromDatabase {
// Setup the database object
sqlite3 *database;
// Initialize the budgetobjects Array
Part1Array = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from part1TBL";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
// You can add more rows based on your object
NSString *Part1_Name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *Part1_Description = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
// Create a new Restaurant with the data from the database
Part1 *newPart1 = [[Part1 alloc] initWithName:Part1_Name description:Part1_Description];
// Add the budgetobject to BudgetObjectsrantArray
[Part1Array addObject:newPart1];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
// Setup the database object
sqlite3 *database2;
// Initialize the budgetobjects Array
Part2Array = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from part2TBL";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
// You can add more rows based on your object
NSString *Part2_Name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *Part2_Description = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
// Create a new Restaurant with the data from the database
Part2 *newPart2 = [[Part2 alloc] initWithName:Part2_Name description:Part2_Description];
// Add the budgetobject to BudgetObjectsrantArray
[Part2Array addObject:newPart2];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database2);
}
#end
The exc_bad_access highlighted at the end where
sqlite3_close(database2);
I'm not familiar with sqlite, but it looks like the issue with your code is that you're never opening 'database2'. Instead, you open 'database' twice, which looks like a typo.
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
....
sqlite3_close(database);
...
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// <--- This should be &database2
...
sqlite3_close(database2);
EDIT: Please note Mat's answer as well - there's several places where you're using database when you meant to use database2, and you might want to consider just reusing database, or extracting this functionality into a shared function if applicable.

How to call different tables in an "if and else" part of the same database in iPhone?

I have a database. It has two tables in it. I want to call one table in an if condition. How do I call the second table in the else part if the if conditions fail?
This is the code I used:
{
NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DocumentsDirectory = [Paths objectAtIndex:0];
NSString *Path = [DocumentsDirectory stringByAppendingPathComponent:#"StoreList.sqlite"];
// Open the database from the users filessytem.
if (sqlite3_open([Path UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
//*********const char *sqlStatement = "select * from Store where Zipcode ='%#'",inputTxt ;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from Store where Zipcode ='%#' or Address = '%#' or CityName = '%#'",inputTxt, inputTxt, inputTxt];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array.
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
//self.tabBarController.selectedIndex=3;
}
else {
NSLog(#"ELSE PART");
// Open the database from the user's filessytem.
if (sqlite3_open([Path UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
//*********const char *sqlStatement = "select * from Store where Zipcode ='%#'",inputTxt ;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from zipcodes where zip ='35004'"];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
}
}
}
}
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
}
I'm getting the input from the text box. When I give the correct value, which is there in the database, it is working fine, the fetch of the data is correct. If I give the wrong data in the textbox it's not working fine - the else condition fails.
How can this issue be fixed?
When going on else you open the same database again, that's not needed (and might cause some problems as well, haven't tried it). Use a BOOL when running the first (select) statement and set it to YES or NO if it fails or not. After you finish with the first statement check the BOOL value and if ==NO run the second statement.
...
BOOL success = NO;
NSString *sqlStatement = [NSString stringWithFormat:#"select * from Store where Zipcode '%#' or Address = '%#' or CityName = '%#'",inputTxt, inputTxt, inputTxt];
NSLog(#" Query in if :%#",sqlStatement);
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK){
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
//self.tabBarController.selectedIndex=3;
success=YES;
}
}
sqlite3_finalize(compiledStatement);
if(success){
//do the else from your code
NSString *sqlStatement = [NSString stringWithFormat:#"select * from zipcodes where zip ='35004'"];
NSLog(#" Query in if :%#",sqlStatement);
if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK){
// Loop through the results and add them to the feeds array
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *latValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"Latitude:%#",latValue);
NSString *longValue = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSLog(#"Longitude:%#",longValue);
//currentLocationLbl.text=[NSString stringWithFormat:#" %# , %#" ,latValue,longValue];
// delegate.latitudeVal=latValue;
// delegate.longitudeVal=longValue;
txtChangeLocation.text = #"";
isFromChangeLoc=TRUE;
}
}
sqlite3_finalize(compiledStatement);
}
I haven't run it, so it might contain some bugs.