I am inserting Russian words into SQLite DB and inside the database (using some DBMS software) they are looking good. But when I retrieve them, the look like this: —É–ª. –°–∞–º–æ–≥–æ –∫—Ä—É—Ç–æ–≥–æ —á—É–≤–∞–∫–∞.
Insert code:
NSString *sql = #"INSERT INTO (. . .) "
" VALUES (. . . )";
sqlite3_stmt *insert;
int result = sqlite3_prepare_v2(self.db, [sql UTF8String], -1, &insert, NULL);
if (result == SQLITE_OK) {
sqlite3_bind_text(insert, 1, [favouriteAction.nameAction UTF8String], -1, SQLITE_TRANSIENT);
. . .
Select code:
NSString *sql = nil;
sql = [NSString stringWithFormat:#"SELECT * FROM UserFavourites"];
sqlite3_stmt *select;
int result = sqlite3_prepare_v2(self.db, [sql UTF8String], -1, &select, NULL);
NSMutableArray* userFavourites = [[NSMutableArray alloc]initWithCapacity:20];
NSLog(#"SQLITE_OK %d", result);
if (result == SQLITE_OK) {
// sqlite3_bind_int(select, 1, (int)user_id);
while (sqlite3_step(select) == SQLITE_ROW) {
NSMutableArray *values = [[NSMutableArray alloc] initWithCapacity:8];
ActionCreation* ac = [[ActionCreation alloc]init];
// get the nameAction:
[values addObject:
[NSString stringWithFormat:#"%s", sqlite3_column_text(select, 0)]];
How to fix this problem?
Thank you.
Related
I am selecting data from sqlite database. Problem is that using following code it works some time. But lets say we call this method for any other table twice then it shows null select statement for other method. Is any thing wrong in method so that if we use same for other tables some time it works some time not.
-(void)getAssessmentNumber:(NSString *)dbPath{
appDelegate=[[UIApplication sharedApplication]delegate];
NSString*fileDBPath=[[NSBundle mainBundle] pathForResource:#"Database" ofType:#"sqlite"];
if (sqlite3_open([fileDBPath UTF8String], &database) == SQLITE_OK)
{
// NSLog(#"%#",[self getDBPath]);
NSString *querySQL = [NSString stringWithFormat:#"Select Am.AssessmentID , Am.AssessmentName From AssessmentMaster Am LEFT JOIN AssessmentDepartmentMapping M ON M.AssessmentID = Am.AssessmentID LEFT JOIN DepartmentListing d ON d.departmentID =M.departmentID where d.departmentID = '%#'",appDelegate.departmentID];
NSLog(#"%#",querySQL);
const char *sql = [querySQL UTF8String];
sqlite3_stmt *selectstmt;
NSError *error;
[appDelegate.assessmentNumberArray removeAllObjects];
if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
while (sqlite3_step(selectstmt) == SQLITE_ROW)
{
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
AssessmentListening *asmObj = [[AssessmentListening alloc] initWithPrimaryKey:primaryKey];
asmObj.assessmentID=[NSString stringWithFormat:#"%d",primaryKey];
asmObj.assessmentName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
[appDelegate.assessmentNumberArray addObject:asmObj];
}
}
else {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
// sqlite3_finalize(selectstmt);
}
sqlite3_close(database);
}
Is this fine for getting the data from table?
Your code needs a little cleanup.
- (void)getAssessmentNumber:(NSString *)dbPath {
NSString *fileDBPath = [[NSBundle mainBundle] pathForResource:#"Database" ofType:#"sqlite"];
if (sqlite3_open([fileDBPath UTF8String], &database) == SQLITE_OK) {
appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.assessmentNumberArray removeAllObjects];
const char *sql = "Select Am.AssessmentID, Am.AssessmentName From AssessmentMaster Am LEFT JOIN AssessmentDepartmentMapping M ON M.AssessmentID = Am.AssessmentID LEFT JOIN DepartmentListing d ON d.departmentID = M.departmentID where d.departmentID = ?";
sqlite3_stmt *selectstmt;
if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(selectstmt, 0, [appDelegate.departmentID UTF8String], -1, SQLITE_TRANSIENT);
while (sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
AssessmentListening *asmObj = [[AssessmentListening alloc] initWithPrimaryKey:primaryKey];
asmObj.assessmentID = [NSString stringWithFormat:#"%d", primaryKey];
asmObj.assessmentName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
[appDelegate.assessmentNumberArray addObject:asmObj];
}
sqlite3_finalize(selectstmt);
} else {
NSLog(#"Unable to prepare statement: %s", sqlite3_errmsg(database));
}
sqlite3_close(database);
} else {
NSLog(#"Unable to open the database from %#: %s", fileDBPath, sqlite3_errmsg(database);
}
}
Note all of the changes:
Only close the database if it is opened.
Only finalize the statement if it is prepared.
Don't build queries with stringWithFormat. Use the proper sqlite3_bind_xxx function to bind the values to the query. This ensures special characters are escaped and properly deals with quoting.
Use proper error checking. Use sqlite3_errmsg to get the error.
I have a sqlite db and i want to insert row in it . I used this code for inserting rows and make a query.
-(void)InsertRecords{
querySQL1 = #"select category from notes where id=5";
const char * query_stmt = [querySQL1 UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO notes (id, title, content,dataAdd,category) VALUES (\"%#\", \"%#\", \"%#\" ,\"%#\",\"%#\")",
#"5",
#"georgiana",
#"20",
#"12.09.2019",
#"public"];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_stmt *updateStmt = nil;
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if(sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"data inserted");
}
else{
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
}
}
else
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(contactDB));
querySQL1 = #"select id from notes where category LIKE 'public'";
query_stmt = [querySQL1 UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL);
NSString *idNr=#"";
while (sqlite3_step(statement) == SQLITE_ROW)
{
idNr =[NSString stringWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
NSLog(#"%#",idNr);
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
Everything is ok, but when I open the app again, I don't find any value for idNr.
Any useful help will be appreciated.
The NSString allocation is wrong statement, There is no need to alloc NSString object here.
The method stringWithUTF8String: is class method. This will do the allocation for NSString.
Replace your code like below:
NSString *idNr = #"";
while (sqlite3_step(statement) == SQLITE_ROW) {
idNr = [NSString stringWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
}
I am trying to update row in a loop and its not working. I have explained the scenario below
I have got set of values from web services stored in arrays. Now i have to update those values in DB by looping through the array. Below is the code am using:
NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"db_name" ofType:#"sqlite"];
sqlite3 *database;
sqlite3 *database1;
sqlite3_open([dbPath UTF8String], &database1);
sqlite3_open([dbPath UTF8String], &database);
NSInteger loopCnt = 0;
NSString *s = [[NSString alloc] init];
const char *sql;
sqlite3_stmt *selectstmt;
NSString *q = [[NSString alloc] init];
for(NSString *itemId in itemIds)
{
s = [NSString stringWithFormat:#"SELECT * from table where id=%#", itemId];
sql = [s UTF8String];
int result = sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL);
if(result == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
if ((char *)sqlite3_column_text(selectstmt, 0) != NULL)
{
rowNumVal = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
col1 = [values1 objectAtIndex:loopCnt];
col2 = [values2 objectAtIndex:loopCnt];
if([rowNumVal integerValue] > 0)
{
q = [NSString stringWithFormat:#"UPDATE table set col1=?, col2=? WHERE id=?"];
}
}
}
}
sqlite3_finalize(selectstmt);
sqlite3_exec(database1, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
sqlite3_stmt *stmt;
const char *query = [q UTF8String];
if(sqlite3_prepare_v2(database1, query, -1, &stmt, NULL)== SQLITE_OK)
{
if(sqlite3_bind_text(stmt, 1, [col1 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 1 %s", sqlite3_errmsg(database1));
}
if(sqlite3_bind_text(stmt, 2, [col2 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(#"Error while binding column 2 %s", sqlite3_errmsg(database1));
}
if (sqlite3_step(stmt) != SQLITE_DONE){
NSLog(#"Delete commit failed. Error %s", sqlite3_errmsg(database1));
}
if(sqlite3_reset(stmt)!= SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
}
sqlite3_trace(database1, sqliteCallbackFunc, NULL);
sqlite3_finalize(stmt);
if(sqlite3_exec(database1, "COMMIT TRANSACTION", 0, 0, 0) != SQLITE_OK){
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
loopCnt++;
}
sqlite3_close(database);
sqlite3_close(database1);
I am fetching the values using id to check row exists and if exists am updating. Everything logs and runs fine but still DB is not getting updated.
Please let me know where is the issue.
You need to call:
sqlite3_finalize(stmt);
Before:
if(sqlite3_reset(stmt)!= SQLITE_OK)
{
NSLog(#"SQL error %s", sqlite3_errmsg(database1));
}
In current code, you are resetting the prepared SQLite statement to it's initial state before finalizing it.
Another issue is, you are trying to update the database that is located in App Bundle. It won't work, because app bundle is read-only. You need to copy the database to document directory and do the operations on that copied database.
I have done lot of googling on updating the created sqlite table still i did not able to update my table in my sample app .Can any one please tell me what is wrong with my below code .IT works fine till sqlite3_prepare_v2.Once it reach if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK) condition it is not going into this if() condition can any one tell what is happening here?
const char *dbpath = [[self DBPath] UTF8String];
if(sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySql=[NSString stringWithFormat:#"UPDATE Table1 SET AppEndTime = %# WHERE AppID= %d",AppEndTime,appID];
const char *sql=[querySql UTF8String];
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)==SQLITE_OK){
sqlite3_bind_int(statement, 1, sessionID);
sqlite3_bind_text(statement, 6, [sessionEndTime UTF8String], -1, SQLITE_TRANSIENT);
}
}
char* errmsg;
sqlite3_exec(database, "COMMIT", NULL, NULL, &errmsg);
if(SQLITE_DONE != sqlite3_step(statement)){
NSLog(#"Error while updating. %s", sqlite3_errmsg(database));
}
else{
sqlite3_reset(statement);
}
sqlite3_finalize(statement);
sqlite3_close(database);
Please replace you code as given below.I hope it will solve your problem.
if (sqlite3_prepare_v2(database, sql, -1, &Statement1, NULL) == SQLITE_OK) {
sqlite3_bind_text(Statement1, 1, [status UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(Statement1, 2, [messageID UTF8String], -1, NULL);
int success = sqlite3_step(Statement1);
if(success != SQLITE_ERROR)
{
// NSLog(#"Success");
}
sqlite3_finalize(Statement1);
}
Here is my code which update created table. Have a look hope it'll help you.
-(BOOL)updateMyTable{
BOOL isGood = YES;
#try {
NSString *fName = [user_dic valueForKey:#"fName"];
NSString *lName = [user_dic valueForKey:#"lName"];
NSString *email_id = [user_dic valueForKey:#"email_id"];
NSString *employee_id = [user_dic valueForKey:#"employee_id"];
fName= [fName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
lName= [lName stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
email_id= [email_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
employee_id= [employee_id stringByReplacingOccurrencesOfString:#"'" withString:#"''"];
// NSString *autoId = [user_dic valueForKey:#"autoId"];
NSString *sql = [NSString stringWithFormat:#"UPDATE tbl_profile SET fName = '%#', lName = '%#', email_id = '%#' ,employee_id = '%#' WHERE autoId = '%#'",fName,lName,email_id,employee_id,autoId];
[database executeUpdate:sql,nil];
if (MyDelegate.isLogging) {
NSLog(#"edit user QUERY---- >>>>%#",sql);
NSLog(#"edit user RESULT CODE ---- >>>>%d:", [database lastErrorCode]);
NSLog(#"edit user RESULT ERROR MESSAGE ---- >>>>%#",[database lastErrorMessage]);
}
}#catch (NSException *exception) {
isGood = NO;
}
#finally {
}
return isGood;
Please make sure your Sqlite file is in the documents directory,Not in project folder.
Update and insert will work if and only if the file is in the document directory
see this answer
I have an SQLite database in my iOS application. I'm trying to use the SQL function MAX()
- (void) getMaxTime {
if (sqlite3_open([databasePath UTF8String], &timingsDatabase) == SQLITE_OK)
{
NSString *maxTimeStatement = [NSString stringWithFormat:#" SELECT max(NUMBERS) FROM TIMINGS"];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(timingsDatabase, [maxTimeStatement UTF8String], -1, &statement, nil) == SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW) {
massimo = sqlite3_column_int(statement, 0);
NSLog(#"The maximun time is %d seconds ", massimo);
}
sqlite3_finalize(statement);
sqlite3_close(timingsDatabase);
}
}
All the numbers in the column NUMBERS have 6 digits after the coma.
Everything works fine if all the numbers are > 10 or all the numbers are <10.
But (example) when I try to get the max among:
1.339670
2.955537
11.355558
It prints: "The maximun time is 2 seconds" (instead of 11)! I'm struggling to understand why.
*EDIT
This is how my Database was created:
-(void)createDatabase
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
databasePath = [[NSString alloc]initWithString:[documentsDirectory stringByAppendingPathComponent:#"timings.db"]];
if ([[NSFileManager defaultManager] fileExistsAtPath:databasePath] == FALSE)
{
if (sqlite3_open([databasePath UTF8String], &timingsDatabase) == SQLITE_OK)
{
const char *sqlStatement = "CREATE TABLE IF NOT EXISTS TIMINGS (ID INTEGER PRIMARY KEY AUTOINCREMENT, TIMESTAMP TEXT, TIMING TEXT, NUMBERS TEXT)";
char *error;
sqlite3_exec(timingsDatabase, sqlStatement, NULL, NULL, &error);
sqlite3_close(timingsDatabase);
}
}
}
And this is how timings are stored:
-(void)storeTiming
{
if (sqlite3_open([databasePath UTF8String], &timingsDatabase) == SQLITE_OK)
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SSS"];
NSString *insertStatement = [NSString stringWithFormat:#"INSERT INTO TIMINGS (TIMESTAMP, TIMING, NUMBERS) VALUES (\"%#\", \"%#\", \"%f\")", [dateFormatter stringFromDate:startDate], stopWatchLabel.text , intervallo] ;
char *error;
sqlite3_exec(timingsDatabase, [insertStatement UTF8String], NULL, NULL, &error);
sqlite3_close(timingsDatabase);
}
}
Seems that column's data type is string... You should change it to float to use MAX() function.