So I get this error: Prepare failure 'out of memory.' Does anyone know why this would be? Note I tested my sql statement. It works great. Also, I am checking to open the database inside another method. It opens just fine. Any help would be appreciated. Thanks!
+(NSArray *) fetchListForFirstLEvelCategory
{
NSMutableArray * array = [[NSMutableArray alloc]init];
NSString * query;
query = [NSString stringWithFormat:#"select mobile_menu.title from sup_pick join sup_mast as mobile_menu on mobile_menu.custom_link1 = sup_pick.key_id and mobile_menu.show_id = '1D2EA159-A312-4FB5-8FE5-B95879B242BB' and mobile_menu.type = 996 and mobile_menu.active = 1 and mobile_menu.status = 1 where sup_pick.client_id = '2517EFF6-8063-4454-BA5F-23679F51AD5A' and sup_pick.active = 1 and sup_pick.parent_key = 'CB18E277-23E9-4232-A20C-AD4D051C578B' and sup_pick.field_name like '%%0000' Order by sup_pick.field_name,mobile_menu.display_order"];
const char *query_stmt = [query UTF8String];
sqlite3_stmt * sql;
if (sqlite3_prepare_v2(db, query_stmt, -1, &sql, NULL) == SQLITE_OK)
{
while (sqlite3_step(sql)==SQLITE_ROW)
{
NSString* test= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 0)];
[array addObject:test];
}
return array;
}
NSLog(#"%s Prepare failure '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
return nil;
}
+(NSArray *) fetchListForFirstLEvelCategory
{
NSMutableArray * array = [[NSMutableArray alloc]init];
NSString * query;
query = [NSString stringWithFormat:#"select mobile_menu.title from sup_pick join sup_mast as mobile_menu on mobile_menu.custom_link1 = sup_pick.key_id and mobile_menu.show_id = '1D2EA159-A312-4FB5-8FE5-B95879B242BB' and mobile_menu.type = 996 and mobile_menu.active = 1 and mobile_menu.status = 1 where sup_pick.client_id = '2517EFF6-8063-4454-BA5F-23679F51AD5A' and sup_pick.active = 1 and sup_pick.parent_key = 'CB18E277-23E9-4232-A20C-AD4D051C578B' and sup_pick.field_name like '%%0000' Order by sup_pick.field_name,mobile_menu.display_order"];
const char *query_stmt = [query UTF8String];
sqlite3_stmt * sql;
if (sqlite3_prepare_v2(db, query_stmt, -1, &sql, NULL) == SQLITE_OK)
{
while (sqlite3_step(sql)==SQLITE_ROW)
{
NSString* test= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 0)];
[array addObject:test];
}
return array;
}
NSLog(#"%s Prepare failure '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
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 feel I am missing the obvious, the code below pulls back three results "201501, 201502 & 201503" I would like to put each result in its own UITextfield, I could have unto 52 results, can anyone help with the missing code, many thanks
_startWeekText.text = 201501
_endWeekText.text = 201503
- (void)allResults{
const char *dbpath_rm1 = [databasePath UTF8String];
sqlite3_stmt *statementrm1;
if (sqlite3_open(dbpath_rm1, &dataTV) == SQLITE_OK) {NSLog(#"Select db opened");
NSString *querySQLPrm1 = [NSString stringWithFormat:
#"SELECT Wk_Num FROM trendViewData WHERE (Name =\"%#\" ) AND (Wk_Num >= \"%#\" AND Wk_Num <= \"%#\") ",_resultSearchText.text,_startWeekText.text,_endWeekText.text];
const char *query_stmtrm = [querySQLPrm1 UTF8String];
if (sqlite3_prepare_v2(dataTV,
query_stmtrm, -1, &statementrm1, NULL) == SQLITE_OK)
while (sqlite3_step(statementrm1) == SQLITE_ROW) {
NSString *rm1 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statementrm1, 0)];
_wk1.text = rm1;
NSString *rm2 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statementrm1, 0)];
_wk2.text = rm2;
NSString *rm3 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statementrm1, 0)];
_wk3.text = rm3;
}
sqlite3_finalize(statementrm1); }
sqlite3_close(dataTV);NSLog(#"Select db Closed");
NSLog(#"%#",_wk);
}
You could have an array of your UITextField references, and then populate it on the basis of that:
NSArray *fields = #[_wk1, _wk2, _wk3];
NSInteger index = 0;
const char *dbpath_rm1 = [databasePath UTF8String];
sqlite3_stmt *statementrm1;
if (sqlite3_open(dbpath_rm1, &dataTV) == SQLITE_OK) {
NSLog(#"Select db opened");
const char *query_stmtrm = "SELECT Wk_Num FROM trendViewData WHERE (Name = ?) AND (Wk_Num >= ? AND Wk_Num <= ?)";
if (sqlite3_prepare_v2(dataTV, query_stmtrm, -1, &statementrm1, NULL) == SQLITE_OK) {
if (sqlite3_bind_text(statementrm1, 1, [_resultSearchText.text UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(#"Bind 1 failed");
}
if (sqlite3_bind_text(statementrm1, 2, [_startWeekText.text UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(#"Bind 2 failed");
}
if (sqlite3_bind_text(statementrm1, 3, [_endWeekText.text UTF8String], -1, NULL) != SQLITE_OK) {
NSLog(#"Bind 3 failed");
}
while (sqlite3_step(statementrm1) == SQLITE_ROW) {
if (index < [fields count]) {
UITextField *field = fields[index];
NSString *rm = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statementrm1, 0)];
field.text = rm;
index++;
} else {
NSLog(#"Got more results than I was expecting!");
}
}
sqlite3_finalize(statementrm1);
} else {
NSLog(#"prepare failed: %s", sqlite3_errmsg(dataTV));
}
sqlite3_close(dataTV);NSLog(#"Select db Closed");
} else {
NSLog(#"open failed");
}
Also, note, I log messages if any of the SQLite calls fail and I don't use stringWithFormat to build the SQL, but rather I use sqlite_bind_text.
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 have a project needs to use the sqlite in it.
And I also create a singleton object to manage my sql
But I just found out that when I read data in sql,the memory just keep growing,and it seems never release.
the following code is how I read data in my singleton object
- (NSArray*)loadRecordPathData{
#synchronized(self)
{
if(sqlite3_open([FILEPATH UTF8String], &database) == SQLITE_OK)
{
NSMutableArray *pathNames = [[NSMutableArray alloc] init];
NSString *query = #"SELECT * FROM pathData";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
BBRecordPathData *recordPathData = [BBRecordPathData new];
int readed = (int) sqlite3_column_int(statement, 0);
int isFavorite = (int) sqlite3_column_int(statement, 1);
char *pathDescroption = (char *) sqlite3_column_text(statement, 2);
char *pathStopTime = (char *) sqlite3_column_text(statement, 3);
char *pathStartTime = (char *) sqlite3_column_text(statement, 4);
int pathChallange = (int) sqlite3_column_int(statement, 5);
char *pathName = (char *) sqlite3_column_text(statement, 6);
NSString *path_StartTime = (pathStartTime) ?[[NSString alloc] initWithUTF8String:pathStartTime] : nil;
NSString *path_StopTime = (pathStopTime) ? [[NSString alloc] initWithUTF8String:pathStopTime] : nil;
NSString *path_Name = (pathName) ? [[NSString alloc] initWithUTF8String:pathName]:nil;
NSString *path_description = (pathDescroption) ? [[NSString alloc] initWithUTF8String:pathDescroption]: nil;
recordPathData.recordPathName = path_Name;
recordPathData.recordPathStartTime = path_StartTime;
recordPathData.recordPathStopTime = path_StopTime;
recordPathData.recordPathDescription = path_description;
recordPathData.challange = pathChallange;
recordPathData.isFavorite = isFavorite;
recordPathData.readed = readed;
//get contain locations
recordPathData.cotainLocations = [self getLocationsPointFromStartTimeTag:recordPathData.recordPathStartTime]; //<----from another table
if (recordPathData.cotainLocations.count == 0 || recordPathData.cotainLocations.count < 4) {
recordPathData.distance = #"0.000KM";
}else{
NSString *unite = #"M";
float distanceInMeter = 0.0;
for (int i = 3; i < recordPathData.cotainLocations.count; i++) {
if (i <= recordPathData.cotainLocations.count - 2){
CLLocation *startPoint = recordPathData.cotainLocations[i];
CLLocation *endPoint = recordPathData.cotainLocations[i + 1];
distanceInMeter += [startPoint distanceFromLocation:endPoint];
}else{
recordPathData.distance = #"0.000KM";
}
}
if (distanceInMeter > 1000.0) {
unite = #"KM";
distanceInMeter /= 1000.0;
recordPathData.distance = [NSString stringWithFormat:#"%.2f%#",distanceInMeter,unite];
}else{
recordPathData.distance = [NSString stringWithFormat:#"%i%#",(int)distanceInMeter,unite];
}
}
[pathNames addObject:recordPathData];
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return pathNames;
}
return nil;
}
}
any suggestion or advice will be a great help , thanks!
If you're using SQLite from Objective C, you should use a wrapper, such as FMDatabase. It will handle the memory management for you and ensure you don't leak.
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;
}