how to save data to different table of sqlite database - iphone

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]);
}];

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 core data be saved in SQLite file

I saved core data in SQLite file but I am wonder what's the table name in coredata I have three entities one of them is students.
While trying to using SQLite statement to read it it not enter the while
const char *sqlStatement = "SELECT * FROM students";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSLog(aName);
}
}
Any suggestion why not enter the if statement?
Well, you shouldn't be querying your CoreData tables directly, CoreData is there to abstract the storage from the code. You should use NSFetchRequest. But to answer your question, the table will normally be called zstudents.
Are you sure the table is actually called students? The core data underlying sqlite database generally has something like ZStudents as table names. You can use the free SQLite Database browser to view the schema in .sqlite files, but I have to wonder, why are writing SQL statements if you are using Core Data?

Single quote encoding issue reading from sqlite for iPhone

I have created an SQLite db for iPhone to store my data (strings).
I have some data that contains ' single quotes (i.e. don't be tense).
This was inserted into the DB using the normal '' escape for SQLite.
INSERT INTO todo(test) VALUES('don''t be tense');
When I do a select on the data in Terminal I can see the single quote in the record.
don't be tense
My problem is when I read the record in, the single quote is not there in the NSLog:
dont be tense
This is the call to read in the field:
self.text = [NSString stringWIthUTF8String:(char *)sqlite3_column_text(init_statement, 1)];
NSLog(#"%#",self.translation);
I would greatly appreciate help on how to ensure the quote is read in.
Below is the full code, if it helps:
static sqlite3_stmt *init_statement = nil;
#implementation Todo
#synthesize primaryKey,text;
- (id)initWithPrimaryKey:(NSInteger)pk database:(sqlite3 *)db {
if (self = [super init]) {
primaryKey = pk;
database = db;
// Compile the query for retrieving book data. See insertNewBookIntoDatabase: for more detail.
if (init_statement == nil) {
// Note the '?' at the end of the query. This is a parameter which can be replaced by a bound variable.
// This is a great way to optimize because frequently used queries can be compiled once, then with each
// use new variable values can be bound to placeholders.
const char *sql = "SELECT text FROM todo WHERE pk=?";
if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
}
// For this query, we bind the primary key to the first (and only) placeholder in the statement.
// Note that the parameters are numbered from 1, not from 0.
sqlite3_bind_int(init_statement, 1, primaryKey);
if (sqlite3_step(init_statement) == SQLITE_ROW) {
self.text = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement, 0)];
NSLog(#"%#",self.text);
} else {
self.text = #"Nothing";
}
// Reset the statement for future reuse.
sqlite3_reset(init_statement);
}
return self;
}
I fixed it.
It seems that when I was updating the database I didn't delete the old one off the simulator so it was testing with old data the entire time. Stupid mistake!
So there is no issue reading in single quotes from SQLite (probably why I could never find information about it).
Thanks to those who read and tried to help!

iPhone SQLite commands with apostrophes

I'm writing an application for the iPhone that communicates with a SQLite database but I'm running into a small problem. Whenever I try to query information based on a condition that contains an apostrophe, no results are returned.... even if a result that matches the requested condition exists. Let me give some specifics...
SQLite Table
Row--Column1--Column2---------
Test Data - 001
User's Data - 002
Objective-C Code
//Create the sql statement
sqlite3_stmt *sqlStatement;
//Create the name of the category that will be passed in
NSString *categoryName = #"User's Data";
//Create the rest of the SQL query
NSString *sqlQuery = "SELECT * FROM theTableName WHERE Column1 = ?";
//If there are no errors in the SQL query
if (sqlite3_prepare_v2(theDatabase, sqlQuery, -1, &sqlStatement, nil) == SQLITE_OK)
{
//Bind the category name to the sql statement
sqlite3_bind_text(sqlStatement, 1, [categoryName UTF8String], -1, SQLITE_TRANSIENT);
//While there are rows being returned
while (sqlite3_step(sqlStatement) == SQLITE_ROW)
{
//Retrieve row data
}
}
else
{
//Save error message to the application log and terminate the app
NSAssert1(0,#"Error: Failed to prepare the SQL statement with message '%s'.", sqlite3_errmsg(database));
}
//Reset the sql statement
sqlite3_reset(sqlStatement);
I'm semi-new to objective C, so my first thought when writing this code was to sanitize the user inputs. But after doing some research, I read that the sqlite3_bind calls do the necessary sanitation for you. But whenever the code runs, the while loop is skipped right over because there are no rows being returned. It should return the second row from the database table. If I copy/paste the exact same SQL query into a SQL managing program (I use SQLite Manager) (and with the necessary query sanitation of course), it returns the correct data.
I've spent a long time trying to debug this myself and even a greater amount of time trying to search online for a similar problem being explained and resolved, but to no avail. As of now, I just disabled the user's ability to key in an apostrophe on the iPhone's virtual keyboard. But this is a feature I'd love to include in my finished product. Can anyone here offer me any helpful tips? Any kind of help would be greatly appreciated.
For sqlite your request will be (as you can see it is even wrong highlighted):
SELECT * FROM theTableName WHERE Column1 = User's data
And it will wait for the closing ' symbol
You should echo ' symbol, for example in following way:
NSString *sqlQuery = [NSString stringWithFormat:#"SELECT * FROM tableName WHERE Column1=\"%#\"", categoryName];
In this case query will be
select * from theTableName where column1="User's data"
that is completely legal query.
In this case you don't need binding any more and final code will look like:
if (sqlite3_prepare_v2(database, [sqlQuery UTF8String], -1, &sqlStatement, nil) == SQLITE_OK)
{
//While there are rows being returned
while (sqlite3_step(sqlStatement) == SQLITE_ROW)
{
//Retrieve row data
}
}
else
{
//Save error message to the application log and terminate the app
NSAssert1(0,#"Error: Failed to prepare the SQL statement with message '%s'.", sqlite3_errmsg(database));
}
The official character is ''
sanitize with:
NSString *stringToSanitize = #"This is the value with ' character";
NSString *sanitized = [stringToSanitize stringByReplacingOccurrencesOfString:#"'"
withString:#"''"];
Then you can use it on your querys

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.