I try to insert only two integer variable to my sqlite database. I created a database which name is ups.sqlite, it has a one table (upssTable) and the table have two column. But when I open /Users/ds/Library/Application Support/iPhone Simulator/5.0/Applications/FCB4B455-4B7F-4C47-81B6-AC4121874596/SqliteDeneme.app/ups.sqlite there is no data in ups.sqlite. My code is here:
- (IBAction)buttonClick:(id)sender {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ups.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
NSLog(#"database path %#",dbPath);
if(!(sqlite3_open([dbPath UTF8String], &cruddb) == SQLITE_OK))
{
NSLog(#"An error has occured.");
}
if(sqlite3_open([dbPath UTF8String], &cruddb) ==SQLITE_OK){
NSString * str1 =#"1";
NSString * str2 =#"1";
const char *sql = "INSERT INTO upssTable (column1, column2) VALUES (?,?)";
NSInteger result = sqlite3_prepare_v2(cruddb,sql, -1, &stmt, NULL);
NSLog(#"upss %s\n", sqlite3_errmsg(cruddb));
if(result == SQLITE_OK)
{
sqlite3_bind_int(stmt, 1, [str1 integerValue]);
sqlite3_bind_int(stmt, 2, [str2 integerValue]);
}
else
{
NSAssert1(0, #"Error . '%s'", sqlite3_errmsg(cruddb));
}
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
sqlite3_close(cruddb);
}
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"ups.sqlite"];
}
How can I solve this problem? Please help me. Thanks for your reply.
You havent used sqlite3_step() at all. Try this way...
sqlite3 *database;
dbPath=[self.databasePath UTF8String];
if(sqlite3_open(dbPath,&database)==SQLITE_OK)
{
const char *sqlstatement = "INSERT INTO upssTable (column1, column2) VALUES (?,?)";
sqlite3_stmt *compiledstatement;
if(sqlite3_prepare_v2(database,sqlstatement , -1, &compiledstatement, NULL)==SQLITE_OK)
{
NSString * str1 =#"1";
NSString * str2 =#"1";
sqlite3_bind_int(compiledstatement, 1, [str1 integerValue]);
sqlite3_bind_int(compiledstatement, 2, [str2 integerValue]);
if(sqlite3_step(compiledstatement)==SQLITE_DONE)
{
NSLog(#"done");
}
else NSLog(#"ERROR");
sqlite3_reset(compiledstatement);
}
else
{
NSAssert1(0, #"Error . '%s'", sqlite3_errmsg(cruddb));
}
sqlite3_close(database);
}
You are creating your sqlite3 statement, but you aren't actually executing it using sqlite3_step().
Also you appear to be opening the database twice?
Related
I'm trying to add record to SQLite file but nothing happens. I get no error and in console I get that record is inserted in table #"----> RECORD INSERTED". Below you can see the code that I'm using. Please, can someone tell me how to fix this. Thanks for your time and help.
- (void)addRecordToSQLiteDatabase
{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appDBPath = [documentsDirectory stringByAppendingPathComponent:#"ProductiivData.sqlite"];
success = [fileManager fileExistsAtPath:appDBPath];
if (success)
{
const char *databaseCharPath = [appDBPath UTF8String];
if (sqlite3_open(databaseCharPath, &(database)) == SQLITE_OK)
{
char *errorInsert;
const char *insertRecordInPROJECT = "insert into PROJECT values (139, 'TEST1888799')";
if (sqlite3_exec(database, insertRecordInPROJECT, NULL, NULL, &errorInsert))
{
NSLog(#"----> RECORD INSERTED");
}
else
{
NSLog(#"----> RECORD NOT INSERTED -- Error: %s", errorInsert);
}
char *errorSelectAll;
sqlite3_stmt *statement = NULL;
const char *allRecordsFromPROJECT = "select * from PROJECT";
if (sqlite3_prepare_v2(database, allRecordsFromPROJECT, 1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *projectName = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
}
}
else
{
NSLog(#"----> RECORDS NOT SELECTED -- Error: %s", errorSelectAll);
}
}
}
}
Separate insert and select logic, Try following code
Get Database path
+ (NSString *)getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"dbName.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success)
{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"dbName.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
return dbPath;
}
Insert Data
+ (void)insertData
{
const char *dbpath = [[self getDBPath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *strSQL = [NSString stringWithFormat:#"INSERT INTO tableName………………."];
const char *insertQuery = [strSQL UTF8String];
sqlite3_stmt *insert_stmt;
if (sqlite3_prepare_v2(database, insertQuery, -1, &insert_stmt, NULL) == SQLITE_OK)
{
if (sqlite3_step(insert_stmt) == SQLITE_DONE)
{
// Code
}
else
{
NSLog(#"error");
}
}
sqlite3_finalize(insert_stmt);
sqlite3_close(database);
}
else
{
NSLog(#"Error in opening database.");
}
}
Get data from table
+ (NSArray *)getDataList
{
NSMutableArray *arrProducts = [[NSMutableArray alloc] init];
const char *dbpath = [[self getDBPath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *strSQL = [NSString stringWithFormat:#"SELECT * FROM tableName"];
const char *selectQuery = [strSQL UTF8String];
sqlite3_stmt *select_stmt;
if(sqlite3_prepare_v2(database, selectQuery, -1, &select_stmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(select_stmt) == SQLITE_ROW)
{
NSInteger productID = sqlite3_column_int(select_stmt, 0);
NSString productNo = [NSString stringWithUTF8String:(char *)sqlite3_column_text(select_stmt, 1)];
// Store above data into dictionary or object and then add this to array
[arrProducts addObject:dict];
}
}
}
else
{
NSLog(#"Error in opening database.");
}
return arrProducts;
}
I have the following code that pushes information to a database. It gives a successful insert but the "canvas" column (the one that contains the image blob) is NULL. I have modeled my use of sqlite3_prepare_v2 and sqlite3_bind_blob after other answers that I've been looking at on StackOverflow.
-(void) sendMoment: (Album *) alb moment:(Moment *) m
{
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
// First, test for existence of writable file:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"pictures.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:writableDBPath];
if (!success){
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"pictures.sqlite"];
success = [fileMgr copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyy-MM-dd HH:mm:ss"];
NSString *dateString = [dateFormat stringFromDate: m.timestamp];
//add passed-in moment to the given album
sqlite3_stmt *sqlStatement;
NSData *imageData = UIImageJPEGRepresentation([m.moment firstObject], 1.0);
NSString *deleteSQL = [NSString stringWithFormat:#"DELETE FROM MomentTbl WHERE user = \"t-amkruz\""];
NSString *momentInsertSQL = [NSString stringWithFormat:#"INSERT INTO MomentTbl (momentID, albumID, title, timestamp, author, latitude, longitude, canvas) VALUES (NULL, %d, '%#', '%#', '%#', '%#', '%#', ?)", alb.ID, alb.title, dateString, #"user", m.latitude, m.longitude];
const char *query_stmt = [momentInsertSQL UTF8String];
const char *dbPath = [writableDBPath UTF8String];
int result = sqlite3_open(dbPath, &db);
if (SQLITE_OK == result) {
char *errInfo = nil;
sqlite3_prepare_v2(db, query_stmt, -1, &sqlStatement, NULL);
sqlite3_bind_blob(sqlStatement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
result = sqlite3_exec(db, query_stmt, nil, nil, &errInfo);
if (SQLITE_OK == result) {
NSLog(#"Sucessful insert");
} else {
NSLog(#"Insert failed");
}
sqlite3_close(db);
}
else {
NSLog(#"Could not open database");
}
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
}
Again, the only part that I have any problems with is the last column; values from every other column insert correctly. I've verified that imageData is non-nil. The prepare_v2 statement and the bind_blob statement both return 0 when I check them with NSLog. I would really appreciate help!
Turns out that I needed to replace the exec statement (and subsequent if statement) with the following:
if(sqlite3_step(sqlStatement) == SQLITE_OK){
NSLog(#"Sucessful insert");
}
else {
NSLog(#"Insert failed");
}
Hope this helps someone else.
I am trying to delete all the rows in database for that I wrote following codes ..
- (id)init {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"dataBase.sqlite3"];
bool databaseAlreadyExists = [[NSFileManager defaultManager] fileExistsAtPath:databasePath];
if (!databaseAlreadyExists){
NSString *databasePathFromApp = [[NSBundle mainBundle] pathForResource:#"dataBase" ofType:#"sqlite3"];
[[NSFileManager defaultManager] copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
if (sqlite3_open([databasePath UTF8String], &_database) == SQLITE_OK){
}
return self;
}
-(void)deleteAll{
NSString *query = #"DELETE FROM user_info";
sqlite3_stmt *statement = nil;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
NSLog(#"Should delete..");
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
But when I rebuild the app data data appears. Whats wrong I am doing?
You never call sqlite3_step to actually execute the query.
Also, you close the database in the wrong place. Your close should be done opposite of the open.
First of all, get the database path after that open database
NSString *dbPath1=[SqliteManager getDataBasePath];
if (sqlite3_open([dbPath1 UTF8String], &database) == SQLITE_OK)
{
NSLog(#"opened the data base");
const char *sql = "delete from travels";
if(sqlite3_prepare_v2(database, sql, -1, &deletestmt, NULL) == SQLITE_OK)
if(SQLITE_DONE != sqlite3_step(deletestmt))
NSAssert1(0, #"Error while deleting. '%s'", sqlite3_errmsg(database));
else
isdeleted=YES;
}
sqlite3_reset(deletestmt);
sqlite3_close(database);
write in ur method inside.....
Getting Database Path....
+(NSString *)getDataBasePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSLog(#"file Path is %#",documentsDir);
return [documentsDir stringByAppendingPathComponent:#"Give ur Sqlite Filename"];
}
Try a conditional if:
if(sqlite3_prepare_v2(database, sql, -1, &deletestmt, NULL) != SQLITE_OK)
This is the code that I have used in Appdelegate.m to copy the database
- (void) copyDatabaseIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"LocalSongs.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
And this is used to get the DBPath
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"LocalSongs.sqlite"];
}
This is my playlist Insert method
-(NSString *)InsertPlaylist :(NSString *)PlaylistName
{
NSLog(#"passed");
NSString *status;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath=[[NSString alloc]initWithString:[documentsDir stringByAppendingPathComponent:#"LocalSongs.sqlite"]];
NSLog(#"Database Path %#",dbPath);
sqlite3_stmt *statement;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSLog(#"open");
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO LOCALPLAYLIST (PLAYLISTNAME,getdate()) VALUES (\"%#\")",PlaylistName];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
status=#"Playlist Created";
}
else
{
status=#"Error occured";
}
return status;
}
}
The problem I have is this prepare_v2 is always become notdone. It always execute the else part.
if (sqlite3_step(statement) == SQLITE_DONE)
What is the problem with this? Please help me
I think you have an error with your query: you are supposed to put a column name in the place you put getdate(), i.e. instead of
INSERT INTO LOCALPLAYLIST (PLAYLISTNAME,getdate()) VALUES (\"%#\")
you should use something like
INSERT INTO LOCALPLAYLIST (PLAYLISTNAME,MYDATECOLUMN) VALUES (\"%#\",getdate())
After sqlite3_prepare_v2 the statement pointer is NULL?
Compare the return values of sqlite3_prepare_v2 and sqlite3_step with the ones in http://www.sqlite.org/c3ref/c_abort.html to get a better insight on what's going wrong
I am using sqlite database mathFActs in my project which i create through Sqlite Database Browser and add it to Xcode. following is my code from a view controller class
- (void)viewDidLoad
{ [super viewDidLoad];
[self copyDatabaseIfNeeded];
[self getInitialDataToDisplay:[self getDBPath]];
}
- (void) copyDatabaseIfNeeded {
//Using NSFileManager we can perform many file system operations.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPth = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPth];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"mathFActs"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"mathFActs"];
}
-(void) getInitialDataToDisplay:(NSString *)databasePath{
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(#"open");
const char *sql = "select Question from math ";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"prepare");
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(selectstmt, 0)];
//address.text = addressField;
qstn.text=addressField;
sqlite3_finalize(selectstmt);
}}
else
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}
}
when i run the project it print open but not prepare means it's not executing query statement .. plz help me to solve my problem
Try this :-
-(void) getInitialDataToDisplay:(NSString *)databasePath
{
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"open");
const char *sql = "select Question from math ";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"prepare");
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(selectstmt, 0)];
//address.text = addressField;
qstn.text=addressField;
}
sqlite3_reset(selectstmt);
}
else
{
NSLog(#"Error: failed to select details with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_finalize(selectstmt);
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}
}
EDIT :-
-(void)copyDatabaseIfNeeded
{
#try
{
NSFileManager *fmgr=[NSFileManager defaultManager];
NSError *error;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *path=[paths objectAtIndex:0];
dbPath=[path stringByAppendingPathComponent:#"mathFActs.sqlite"];
if(![fmgr fileExistsAtPath:dbPath]){
NSString *defaultDBPath=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"Addict.sqlite"];
if(![fmgr copyItemAtPath:defaultDBPath toPath:dbPath error:&error])
NSLog(#"failure message----%#",[error localizedDescription]);
}
}
#catch (NSException *exception)
{
NSLog(#"Exception: %#", exception);
}
}
-(NSString *)getDBPath
{
//Search for standard documents using NSSearchPathForDirectoriesInDomains
//First Param = Searching the documents directory
//Second Param = Searching the Users directory and not the System
//Expand any tildes and identify home directories.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"mathFActs.sqlite"];
}
-(void)openDatabase
{
[self copyDatabaseIfNeeded];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
//Database Opened
NSLog(#"Database opened");
}
else
{
NSLog(#"Database cannot be opened");
}
}
-(void)closeDatabase
{
sqlite3_close(database);
}
Hope it helps you