I have tried following the guide on this page SQLite Tutorial? Deleting Data | iPhone SDK Articles but I just can't understand how to implement it in my app, because I the NSMutableArray isn't declared in the AppDelegate as it is in the tutorial
Can someone have a look and guide me through it? I want to be able to delete rows from the tableview and the database and to be able to add data as well.
Here is my app: http://ge.tt/9JNVd89?c
Even the slightest tip will be appreciated.
Will probably need a bit more information as to your current level of knowledge. How far have you gotten? Are you able to connect and read data from it? Do you understand how SQL works?
If you wanted to retrieve data from the db you could write something like the following:
+ (NSArray *)getAllUsers
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSMutableArray *userArray = [NSMutableArray array];
NSString *fullQuery = #"SELECT * FROM User";
const char *sql = [fullQuery UTF8String];
if(sqlite3_prepare_v2(db, sql, -1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0, #"Error preparing statement '%s'", sqlite3_errmsg(db));
else
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
User *currentUser = [[User alloc] init];
[User setPk:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)]];
[User setName:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)]];
[User setAge:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)]];
[userArray currentUser];
[currentUser release];
}
}
sqlite3_finalize(statement);
sqlite3_close(db);
return [NSArray arrayWithArray:userArray];
}
and if you wanted to insert data into it:
+ (void)insertUser:(NSString *)username
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSString *fullQuery = [NSString stringWithFormat:#"INSERT INTO User (userName) VALUES (%#);", username];
const char *sql = [fullQuery UTF8String];
sqlite3_prepare_v2(db, sql2, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"User inserted");
}
sqlite3_finalise(statement);
sqlite3_close(db);
}
If you are having trouble getting a database into your application and connecting to it, let me know and I can post some of that code as well.
Hope that helps :)
Related
I try to retrieve data from sqlite. Unfortunately the table is filled with null values.
The console shows FIRST ID RECUPERÉ : (null). Can you give me your opinions please?
This is the code:
NSString * statementID = [NSString stringWithFormat:#"SELECT id_message FROM messages;"];
const char * sql_stmt_id = [statementID UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(contactDB, sql_stmt_id, -1, &compiledStatement, NULL) == SQLITE_OK)
{
[tableauMsgReceived removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
[tableauMsgReceived addObject:[NSString stringWithFormat:#"%s",(char *) sqlite3_column_text(compiledStatement, 0)]];
NSLog(#"First ID : %#", [tableauMsgReceived objectAtIndex:0]);
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(contactDB);
The only way that the NSLog statement will give that result given your code is if tableauMsgReceived is nil.
Somewhere you need to do:
tableauMsgReceived = [[NSMutableArray alloc] init];
First of all, make sure you have done something like
tableauMsgReceived = [[NSMutableArray alloc] init];
Then, check whether database opened successfully
if (sqlite3_open([YourDBPath UTF8String], &yourDatabase) == SQLITE_OK){}
Last thing, maybe you can try
[tableauMsgReceived addObject:[NSString stringWithUTF8String:(const char *)sqlite3_column_text(statement, 0)]];
I want to saving entire array into SQLite. I am getting an array having many other arrays in that.
Is it possible ? If so please let tell me.
I have tried this - But "ERROR TO SAVE DATA"
NSArray *array = [dict objectForKey:#"events_data"];
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO CONTACTS (event_array) VALUES (\"%#\")", array];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"DATA SAVED TO DB");
} else {
NSLog(#"ERROR TO SAVE DATA");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
If it is possible please tell me how to retrieve it also.
You need not use sqlite directly in iOS. Indeed, you should wrap the persistent object in an NSManagedObject. To retrieve the object, simply create an NSFetchRequest, set its entity, and have the context execute it, which will return a standard NSArray of NSManagedObjects, which you can iterate over. Hope this helped, please leave a comment if you have further issues.
Here i want to execute query using two database and copy data from table of database1 to another database2. here i am able to open one database but getting problem in openning other database. Thanks in advance to all.
CurrentStatus *status = [CurrentStatus sharedCurrentStatus];
sqlite3 *database;
sqlite3 *database1;
sqlite3_stmt *statement;
sqlite3_stmt *statement1;
NSString *dbPath = [status.applicationDocumentDirectory stringByAppendingPathComponent:#"database.sqlite"];
NSString *dbPath1 = [status.applicationDocumentDirectory stringByAppendingPathComponent:#"database1.sqlite"];
if ((sqlite3_open_v2([dbPath UTF8String], &database, SQLITE_OPEN_READWRITE , NULL) == SQLITE_OK) && (sqlite3_open_v2([dbPath1 UTF8String], &database1, SQLITE_OPEN_READWRITE , NULL) == SQLITE_OK)) {
NSString *sqlStr = [[NSString alloc] initWithFormat:#"select * from Login" ];
NSString *sql = [[NSString alloc] initWithString:sqlStr];
if ((sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)) {
NSLog(#"DB prepare_v2 Opening successfully");
if (sqlite3_step(statement) == SQLITE_ROW) {
}
else
{
}
sqlite3_finalize(statement);
NSLog(#"DB Opening successfully");
sqlite3_close(database);
}else
{
NSLog(#"else DB Opening successfully");
}
sqlite3_close(database);
}
Try something similar to achieve your task ..
First, you are opening the "DB1" database, and then execute the following statement:
ATTACH DATABASE "2ndDB.db" AS 2ndDB;
After that, you can use the CREATE TABLE syntax:
CREATE TABLE newTableInDB1 AS SELECT * FROM 2ndDB.oldTableInMyOtherDB;
This will "copy" the data over to your new database
Copy which are the data you want it from database1 add each row in NSMutableDictionary and then add it to NSMutableArray. Close and reset your statement then open the database2 copy the data from NSMutableArray, that array act as database for you..
I hope it will work for you..
You need to You need to Attach databases and then copy tables from one database to another database. You need to do something like this:
NSString *attachSQL = [NSString stringWithFormat: #"ATTACH DATABASE \'%s\' AS %#", sourceDBPath,dbAlias];
if (sqlite3_exec(db, [attachSQL UTF8String], NULL, NULL, &errorMessage) != SQLITE_OK)
{
NSString *errorStr = [NSString stringWithFormat:#"The database could not be attached: %#",[NSString stringWithCString:errorMessage encoding:NSUTF8StringEncoding]];
return errorStr;
}
After that you need to copy table , like:
NSString *queryString=[NSString stringWithFormat:#"CREATE TABLE %# AS SELECT * FROM %#.%#;",newTableName,dbAlias,origTableName];
And you are done, you have the new copy of database.
Hi can anyone point out what I'm doing wrong please? The error is this:
SQL error 'out of memory' (7)
- (NSArray *)RecipeInfo
{
NSMutableArray *retval = [[NSMutableArray alloc] init];
NSString *query = [NSString stringWithFormat:#"SELECT key, name FROM recipes WHERE type = \'%#\'", self.RecipeType];
NSLog(query);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK)
{
NSLog(#"[SQLITE] Error when preparing query!");
NSLog(#"%s SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(_database), sqlite3_errcode(_database));
}
else
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
int uniqueId = sqlite3_column_int(statement, 0);
char *nameChars = (char *) sqlite3_column_text(statement, 1);
NSString *name = [[NSString alloc] initWithUTF8String:nameChars];
RecipeInfo *info = [[RecipeInfo alloc] initWithUniqueId:uniqueId name:name];
[retval addObject:info];
}
sqlite3_finalize(statement);
}
return retval;
}
The sql executes fine in the database management environment I use, it has to be something to do with the way I'm using the sql api, can anyone spot whats wrong?
You can get that error, confusingly, if you neglected to open the database and the pointer is NULL (or, as rmaddy says, if it's NULL for any reason). Put a log statement where you open the database and make sure that it was successful and that you have a valid sqlite3 pointer.
I have a DBManager wich is fetching data from database (sqlite file). All other queries are fine, but this one seems to be somehow not working
-(NSArray *)readCountries{
NSLog(#"[DBManager] readCountries");
NSMutableArray *countriesArray = [[NSMutableArray alloc] init];
//open db from users filesystem
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char* sql = "SELECT DISTINCT country FROM aed ORDER BY rowid";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
//loop through results
while (sqlite3_step(statement) == SQLITE_ROW) {
//read data from record
NSString *_country;
char* tmpCountry = (char*)sqlite3_column_text(statement, 1);
NSLog(#"tmpCountry = %#", [NSString stringWithUTF8String:tmpCountry]);
if (tmpCountry != NULL) {
_country = [NSString stringWithUTF8String:tmpCountry];
}else{
_country = #"n/a";
}
NSLog(#"country = %#", _country);
[countriesArray addObject:_country];
}
}
//finalize statement
sqlite3_finalize(statement);
}
//close database
sqlite3_close(database);
NSLog(#"[DBManager] countriesArray has %d objects", [countriesArray count]);
return (NSArray*)countriesArray;
}
All I get from logs, that my array has 5 objects, which is fine - but it souldn't be only "n/a"... any idea? Other queries are good, they mostly use sqlite3_column_text so I don't get it, why it's not working here - maybe a fresh eye will help.
This is a confusing inconsistency with the sqlite C-api. When using the sqlite3_column_xxx functions, the column index is 0-based. But with the sqlite3_bind_xxx functions, the column index is 1-based.
Change this:
char* tmpCountry = (char*)sqlite3_column_text(statement, 1);
to:
char* tmpCountry = (char*)sqlite3_column_text(statement, 0);
BTW - you should add else statements to your sqlite3_open and sqlite3_prepare calls. If they fail you can log the error using the sqlite3_errmsg function.