How can I retrieve sqlite3 table names in objective-c.For example if I created several tables, now i want to get (display) their names like .table in terminal.Thanks.
Use below code:
-(NSMutableArray *)fetchTableNames
{
sqlite3_stmt* statement;
NSString *query = #"SELECT name FROM sqlite_master WHERE type=\'table\'";
int retVal = sqlite3_prepare_v2(YOUR_DB_OBJ,
[query UTF8String],
-1,
&statement,
NULL);
NSMutableArray *selectedRecords = [NSMutableArray array];
if ( retVal == SQLITE_OK )
{
while(sqlite3_step(statement) == SQLITE_ROW )
{
NSString *value = [NSString stringWithCString:(const char *)sqlite3_column_text(statement, 0)
encoding:NSUTF8StringEncoding];
[selectedRecords addObject:value];
}
}
sqlite3_clear_bindings(statement);
sqlite3_finalize(statement);
return selectedRecords;
}
SELECT name FROM sqlite_master WHERE type='table'
SELECT * FROM sqlite_master where type='table'
try this.
- (NSArray *)listOfColumnNamesForTable:(NSString *)tableName WithDBFilePath:(NSString*)databasePath {
sqlite3 *sqlite3Database;
NSMutableArray *columnNames = [NSMutableArray array];
int openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
if(openDatabaseResult == SQLITE_OK) {
sqlite3_stmt *compiledStatement;
NSString *query = [NSString stringWithFormat:#"pragma table_info ('%#')",tableName];
int prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, [query UTF8String], -1, &compiledStatement, NULL);
if(prepareStatementResult == SQLITE_OK) {
sqlite3_stmt* statement;
int retVal = sqlite3_prepare_v2(sqlite3Database,
[query UTF8String],
-1,
&statement,
NULL);
if ( retVal == SQLITE_OK )
{
while(sqlite3_step(statement) == SQLITE_ROW )
{
NSString *value = [NSString stringWithCString:(const char *)sqlite3_column_text(statement, 1)
encoding:NSUTF8StringEncoding];
[columnNames addObject:value];
}
}
sqlite3_clear_bindings(statement);
sqlite3_finalize(statement);
sqlite3_close(sqlite3Database);
return [columnNames mutableCopy];
}
}
sqlite3_close(sqlite3Database);
return nil;
}
Related
I have created multiple tables in my database. And now I want insert data into those tables. How to insert multiple tables data can anyone help regarding this.
I have written this code for creating 1 table:
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO ATRG (id, name, language,imgurl) VALUES ( \"%#\",\"%#\",\"%#\",\"%#\")", ID, name, lang,imgUrl];
const char *insert_stmt = [insertSQL UTF8String]; sqlite3_prepare_v2(_globalDataBase, insert_stmt, -1, &statement, NULL); if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Record Inserted");
} else { NSLog(#"Failed to Insert Record");
}
Try this I hope it would be helpful!! This is mine code for insert data
#import "Sqlitedatabase.h"
#implementation Sqlitedatabase
+(NSString* )getDatabasePath
{
NSString *docsDir;
NSArray *dirPaths;
sqlite3 *DB;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *databasePath = [docsDir stringByAppendingPathComponent:#"myUser.db"];
NSFileManager *filemgr = [[NSFileManager alloc]init];
if ([filemgr fileExistsAtPath:databasePath]==NO) {
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath,&DB)==SQLITE_OK) {
char *errorMessage;
const char *sql_statement = "CREATE TABLE IF NOT EXISTS users(ID INTEGER PRIMARY KEY AUTOINCREMENT,FIRSTNAME TEXT,LASTNAME TEXT,EMAILID TEXT,PASSWORD TEXT,BIRTHDATE DATE)";
if (sqlite3_exec(DB,sql_statement,NULL,NULL,&errorMessage)!=SQLITE_OK) {
NSLog(#"Failed to create the table");
}
sqlite3_close(DB);
}
else{
NSLog(#"Failded to open/create the table");
}
}
NSLog(#"database path=%#",databasePath);
return databasePath;
}
+(NSString*)encodedString:(const unsigned char *)ch
{
NSString *retStr;
if(ch == nil)
retStr = #"";
else
retStr = [NSString stringWithCString:(char*)ch encoding:NSUTF8StringEncoding];
return retStr;
}
+(BOOL)executeScalarQuery:(NSString*)str{
NSLog(#"executeScalarQuery is called =%#",str);
sqlite3_stmt *statement= nil;
sqlite3 *database;
BOOL fRet = NO;
NSString *strPath = [self getDatabasePath];
if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE)
fRet =YES;
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return fRet;
}
+(NSMutableArray *)executeQuery:(NSString*)str{
sqlite3_stmt *statement= nil; // fetch data from table
sqlite3 *database;
NSString *strPath = [self getDatabasePath];
NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSInteger i = 0;
NSInteger iColumnCount = sqlite3_column_count(statement);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
while (i< iColumnCount) {
NSString *str = [self encodedString:(const unsigned char*)sqlite3_column_text(statement, (int)i)];
NSString *strFieldName = [self encodedString:(const unsigned char*)sqlite3_column_name(statement, (int)i)];
[dict setObject:str forKey:strFieldName];
i++;
}
[allDataArray addObject:dict];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return allDataArray;
}
#end
And called that method where you want to use!!
NSString *insertSql = [NSString stringWithFormat:#"INSERT INTO users(firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
if ([Sqlitedatabase executeScalarQuery:insertSql]==YES)
{
[self showUIalertWithMessage:#"Registration succesfully created"];
}else{
NSLog(#"Data not inserted successfully");
}
And If you want to fetch data from table then you can do this!!
NSString *insertSql = [NSString stringWithFormat:#"select emailid,password from users where emailid ='%#' and password = '%#'",[_usernameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],[_passwordTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSMutableArray *data =[Sqlitedatabase executeQuery:insertSql];
NSLog(#"Fetch data from database is=%#",data);
Multiple Execute Query!!
NSString *insertSql = [NSString stringWithFormat:#"INSERT INTO users (firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
NSString *insertSql1 = [NSString stringWithFormat:#"INSERT INTO contact (firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
NSMutableArray * array = [[NSMutableArray alloc]initWithObjects:insertSql,insertSql1,nil];
for (int i=0; i<array.count; i++)
{
[Sqlitedatabase executeScalarQuery:[array objectAtIndex:i]];
}
See this for your issue:
Insert multiple tables in same database in sqlite
or if you want
Multi-table INSERT using one SQL statement in AIR SQLite
then use this:
http://probertson.com/articles/2009/11/30/multi-table-insert-one-statement-air-sqlite/
I'm using sqlite to use insert and update the data in table view. I can able to update the data only once, on the next attempt it showing database locked. Even though am closing the database, please help. Below is the code.
-(void)saveUserCredential: (NSString *)email :(NSString *)userName :(NSString *)loginTime :(NSString *)source
{
NSDateFormatter *dateformate=[[NSDateFormatter alloc]init];
[dateformate setDateFormat:#"yyyy-MM-dd HH:mm"]; // Date formater
NSString *todayDate = [dateformate stringFromDate:[NSDate date]];
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString * query = #"SELECT * from users";
int rc =sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL);
if(rc == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *updateSQL = [NSString stringWithFormat:#"update users set email = '%#', username = '%#', source = '%#', created = '%#' where id = '%d'",email, userName, source, todayDate,1];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL );
//sqlite3_bind_int(statement, 1, 1);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"successfully updated");
}
else{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
}
else
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into users (email,username,source,created) values('%#','%#','%#','%#')",email,userName,source,todayDate];
NSLog(#"INS SQL: %#", insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"INSERTED");
}
else
{
NSLog(#"NOT INSERTED");
}
NSLog(#"hello ");
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
}
You need to call
sqlite3_finalize(statement);
for each successful sqlite_prepare_v2 call. It should be balanced. Also use different sqlite3_stmt for each query.
So your code need to be changed like:
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString * query = #"SELECT * from users";
int rc =sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL);
if(rc == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *updateSQL = [NSString stringWithFormat:#"update users set email = '%#', username = '%#', source = '%#', created = '%#' where id = '%d'",email, userName, source, todayDate,1];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_stmt *upStmt;
sqlite3_prepare_v2(database, update_stmt, -1, &upStmt, NULL );
//sqlite3_bind_int(upStmt, 1, 1);
if (sqlite3_step(upStmt) == SQLITE_DONE)
{
NSLog(#"successfully updated");
}
else
{
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(upStmt);
}
else
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into users (email,username,source,created) values('%#','%#','%#','%#')",email,userName,source,todayDate];
NSLog(#"INS SQL: %#", insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_stmt *inStmt;
sqlite3_prepare_v2(database, insert_stmt,-1, &inStmt, NULL);
if (sqlite3_step(inStmt) == SQLITE_DONE)
{
NSLog(#"INSERTED");
}
else
{
NSLog(#"NOT INSERTED");
}
NSLog(#"hello ");
sqlite3_finalize(inStmt);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
I have a table in a database which I access like this:
+(NSMutableArray *) queryDatabaseWithSQL:(NSString *)sql params:(NSArray *)params {
sqlite3 *database;
NSMutableArray *rtn = [[NSMutableArray alloc] init];
int index = 0;
NSString *filepath = [self copyDatabaseToDocumentsWithName:#"database"];
if (sqlite3_open([filepath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = [sql cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
if ([params count]) {
for (int i = 0; i < [params count]; i++) {
NSString *obj = [params objectAtIndex:i];
sqlite3_bind_blob(compiledStatement, i + 1, [obj UTF8String], -1, SQLITE_TRANSIENT);
}
}
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSMutableArray *arr = [[NSMutableArray alloc] init];
index = 0;
const char *s = (char *)sqlite3_column_text(compiledStatement, index);
while (s) {
[arr addObject:[NSString stringWithUTF8String:s]];
index++;
s = (char *)sqlite3_column_text(compiledStatement, index);
}
if (![rtn containsObject:arr]) {
[rtn addObject:arr];
}
}
}
sqlite3_finalize(compiledStatement);
}
NSLog(#"ERROR: %s", sqlite3_errmsg(database));
sqlite3_close(database);
return rtn;
}
This works fine when I call the function like this:
NSLog(#"%#", [database queryDatabaseWithSQL:#"SELECT * FROM FRIENDSUSERS WHERE USER = ?" params:#[[delegate->user objectForKey:#"username"]]]);
Then when I call the function using a string like this it doesn't return any rows:
NSLog(#"%#", [database queryDatabaseWithSQL:#"SELECT * FROM FRIENDSUSERS WHERE USER = ?" params:#[#"username"]]);
I haven't got a clue what is going one with but I have checked the strings match and they do so I'm now stuck
Can anyone see any reason why this would not work
I have run error checks as well and every time it returns no error, or rows :(
Thanks in advance
I am making a function which allows you to read from a database and then puts the data into a NSMutableArray which it later returns for the user. Though for some reason when it is about to return the data the data is deleted from the array. Here is the code for the function:
+(NSMutableArray *) readFromDataBaseWithName:(NSString *)name withSqlStatement:(NSString *)sql {
sqlite3 *database;
NSMutableArray *rtn = [[NSMutableArray alloc] init];
NSMutableArray *new = [[NSMutableArray alloc] init];
int index = 0;
NSString *filePath = [self copyDatabaseToDocumentsWithName:name];
if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStateMent = [sql cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare(database, sqlStateMent, -1, &compiledStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
// loop through elements in row and put them into array
const char *s = (char *)sqlite3_column_text(compiledStatement, index);
while (s) {
[new addObject:[NSString stringWithUTF8String:s]];
index++;
s = (char *)sqlite3_column_text(compiledStatement, index);
}
[rtn addObject:new];
[new removeAllObjects];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return rtn;
}
Any advice would be much appreciated.
You keep reusing new. You need to create individual arrays each time.
+(NSMutableArray *) readFromDataBaseWithName:(NSString *)name withSqlStatement:(NSString *)sql {
sqlite3 *database;
NSMutableArray *rtn = [[NSMutableArray alloc] init];
int index = 0;
NSString *filePath = [self copyDatabaseToDocumentsWithName:name];
if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStateMent = [sql cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare(database, sqlStateMent, -1, &compiledStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
// loop through elements in row and put them into array
NSMutableArray *new = [[NSMutableArray alloc] init];
const char *s = (char *)sqlite3_column_text(compiledStatement, index);
while (s) {
[new addObject:[NSString stringWithUTF8String:s]];
index++;
s = (char *)sqlite3_column_text(compiledStatement, index);
}
[rtn addObject:new];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return rtn;
}
below is my code to update records in database...
-(BOOL) addScoreInDatabase:(classname *)objGames
{
BOOL success;
sqlite3 *database;
const char *dbpath = [self.databasePath UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
sqlite3_stmt *statement;
NSData *strJson = [objGames getJSON];
NSString *strContent = [[[[NSString alloc]
initWithData:strJson encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:#"\\" withString:#""]stringByReplacingOccurrencesOfString:#"null" withString:#"\"\""];
NSLog(#"strcom %#",strContent);
NSString *query = [NSString stringWithFormat:#"UPDATE gamescore SET data ='%#' WHERE id = 1",strContent];
NSLog(#"query %#",query);
const char *sqlStatement = [query UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, & statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = TRUE;
}
else
{
success = FALSE;
}
sqlite3_exec(database, "VACUUM;", 0, 0, nil);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return success;
}
and it doesn't go inside if (sqlite3_step(statement) == SQLITE_DONE) loop
and Resulted query is
UPDATE gamescore SET data ='{
"title" : "pacman",
"time" : "55",
"score" : "200",
"level" : "1"
}' WHERE id = 1
and when i execute this query in Sqlite Manager it doesn't update the records instead it shows something like this
Can anybody help me to update my records ?!..Thanks !!
You can use sqlite3_exec() method instead of sqlite3_step().
sqlite3_exec() will execute whatever the query you have given.
Try this out.
enter code
-(BOOL) addScoreInDatabase:(classname *)objGames
{
BOOL success;
sqlite3 *database;
const char *dbpath = [self.databasePath UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
sqlite3_stmt *statement;
NSData *strJson = [objGames getJSON];
NSString *strContent = [[[[NSString alloc]
initWithData:strJson encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:#"\\" withString:#""]stringByReplacingOccurrencesOfString:#"null" withString:#"\"\""];
NSLog(#"strcom %#",strContent);
NSString *query = [NSString stringWithFormat:#"UPDATE gamescore SET data ='%#' WHERE id = 1",strContent];
NSLog(#"query %#",query);
const char *sqlStatement = [query UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, & statement, NULL) == SQLITE_OK)
{
sqlite3_exec(database, "VACUUM;", 0, 0, nil);
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return success;
}