I need to update my sqlite table. So I wrote a query like this
NSString *updateSQL = [NSString stringWithFormat: #"UPDATE LOCALPLAYLISTSONGS SET SONGNAME=\"%#\",SONGPATH=\"%#\" WHERE PLAYLISTNAME=\"%#\"",SongTitle,songPath,playlistName];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
status=#"song Added";
}
else
{
status=#"Error occured";
}
The problem is this always shows the status as Error Occured. What is the issue with my query. please show me
Thanks
UPDATE
-(NSString *)UpdateLocalPlaylist :(NSString *)playlistName :(NSString *)SongTitle :
(NSString *)songPath
{
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 *updateSQL = [NSString stringWithFormat: #"UPDATE LOCALPLAYLISTSONGS SET SONGNAME=%#,SONGPATH=%# WHERE PLAYLISTNAME=%#",SongTitle,songPath,playlistName];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
status=#"song Added";
}
else
{
status=#"Error occured";
}
return status;
}
else
return #"Error Occured";
}
SQL use single quotation mark (') for string, not double ("). Double quote is only for object names (tables, columns ...).
try this way...
NSString *updateSQL = [NSString stringWithFormat: #"UPDATE LOCALPLAYLISTSONGS SET
SONGNAME='%#',SONGPATH='%#' WHERE PLAYLISTNAME='%#'",SongTitle,songPath,playlistName];
you try this:
update_stmt = nil;
NSString *updateSQL = [NSString stringWithFormat: #"UPDATE LOCALPLAYLISTSONGS SET SONGNAME=%#,SONGPATH=%# WHERE PLAYLISTNAME=%#",SongTitle,songPath,playlistName];
Just try with this also and let me known
Declare your query in this format (As you declared before)
NSString *updateSQL = [NSString stringWithFormat: #"UPDATE LOCALPLAYLISTSONGS SET SONGNAME=\"%#\",SONGPATH=\"%#\" WHERE PLAYLISTNAME=\"%#\"",SongTitle,songPath,playlistName];
and added a condition like this to check
if (sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL)) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_DONE)
{
status=#"song Added";
}
else
{
status=#"Error occured";
}
}
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 have an app where I take details of the user and save it to SQLite db. Also I am able to find the details and display the result.
-(void) createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"contactUnique6.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT , ADDRESS TEXT, PHONE TEXT )";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
_status.text = #"Failed to create table";
}
sqlite3_close(_contactDB);
} else {
_status.text = #"Failed to open/create database";
}
}
- (IBAction)saveData:(id)sender {
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT OR IGNORE INTO CONTACTS (name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
_name.text, _address.text, _phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
_status.text = #"Contact added";
_name.text = #"";
_address.text = #"";
_phone.text = #"";
} else {
_status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
- (IBAction)findContact:(id)sender {
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT address, phone FROM contacts WHERE name=\"%#\"",
_name.text];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_contactDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *addressField = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
_address.text = addressField;
NSString *phoneField = [[NSString alloc]
initWithUTF8String:(const char *)
sqlite3_column_text(statement, 1)];
_phone.text = phoneField;
_status.text = #"Match found";
} else {
_status.text = #"Match not found";
_address.text = #"";
_phone.text = #"";
}
sqlite3_finalize(statement);
}
sqlite3_close(_contactDB);
}
}
The above code is working good. However when I am trying to use an update, it is not displaying when I try to find it. It gives me a match not found even though the contact was saved.
This is the code by which I am trying to update:
- (IBAction)saveData:(id)sender {
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT OR IGNORE INTO CONTACTS (name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
_name.text, _address.text, _phone.text];
insertSQL = [NSString stringWithFormat:
#"UPDATE CONTACTS SET name=\"%#\", address=\"%#\", phone=\"%#\"",
_name.text, _address.text, _phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
_status.text = #"Contact added";
_name.text = #"";
_address.text = #"";
_phone.text = #"";
} else {
_status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
Basically my aim is to be able to save-update-find. (without losing the primary key on update, as I have FK relations)
EDIT
This is my create db method
-(void) createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"contactUnique6.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT , ADDRESS TEXT, PHONE TEXT )";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
_status.text = #"Failed to create table";
}
sqlite3_close(_contactDB);
} else {
_status.text = #"Failed to open/create database";
}
}
i cant get your second -(IBAction)saveData:(id)sender {} method [ Third code block ]..
You said above 2 blocks are working properly so its ok.
i think you embedded the update's logic in insert's logic i.e. you embedded the update method in your saveData method..
Here i cant get what u have done, so instead of code here i m providing the template for update query, just put your code in it...
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &database_object) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"update table_name set column_name = \"%#\"", Your_value];
const char *sql_stmt = [sql UTF8String];
if(sqlite3_prepare_v2(database_object , sql_stmt, -1, &statement, NULL) != SQLITE_OK)
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(database_object));
if(SQLITE_DONE != sqlite3_step(statement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database_object));
sqlite3_finalize(statement);
}
Go with this template, i think it will work for you...
i want to update my database.database in to regno are not updating but other field updated.means that regno are constant.
-(BOOL) updateData:(NSString*)name
department:(NSString*)department year:(NSString*)year
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
NSString *updateSQL = [NSString stringWithFormat:#"update into studentsDetail name=?, department=?, year=? where regno=? "];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(database, update_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
return YES;
}
else{
return NO;
}
sqlite3_reset(statement);
}
return NO;
}
Update query is wrong.
It should be like this.
UPDATE studentsDetail
SET name=?, department=?,year=?
WHERE regno=?
Try like this,
UPDATE table_name SET column1=value1,column2=value2 WHERE some_column=some_value;
NSString *updateSQL = [NSString stringWithFormat:#"update studentsDetail SET name='%#', department='%#', year='%#' where regno='%#'",#"name",#"dept",#"year",#"regno"];
Im trying to insert just one name to my sqlite file. im using this code but it's not working :/
-(void)InsertRecords:(NSMutableString *) txt{
if(addStmt == nil) {
const char *sql = "INSERT INTO myMovies (movieName) VALUES(?) ";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
else
sqlite3_bind_text(addStmt, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
}
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
sqlite3_reset(addStmt);
}
pass your query to this method and try,
-(void)Insertdata:(NSString*)query{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"YourDBName.sql"];
if(sqlite3_open([databasePath UTF8String],&db) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"%#",query];
char *errmsg=nil;
if(sqlite3_exec(db, [querySQL UTF8String], NULL, NULL, &errmsg)==SQLITE_OK)
{
NSLog(#".. Row Added ..");
}
}
sqlite3_close(db);
}
An "out of memory" error from sqlite typically means the database handle you are using hasn't been opened yet. Make sure you are calling sqlite3_open_v2 with the database variable shown in the code you posted?
ok finally I made it ! this is the code that I used for everyone who need it :
-(void)InsertRecords:(NSMutableString *)txt{
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"movieData.sqlite"];
const char *dbpath = [dbPath UTF8String];
sqlite3 *contactDB;
sqlite3_stmt *statement;
NSLog(#"%#",dbPath);
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO myMovies (movieName) VALUES (\"%#\")", txt];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
sqlite3_bind_text(statement, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
} else {
NSLog(#"error");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
Try this:
//save our data
- (BOOL) saveEmployee:(Employee *)employee
{
BOOL success = false;
sqlite3_stmt *statement = NULL;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &mySqliteDB) == SQLITE_OK)
{
if (employee.employeeID > 0) {
NSLog(#"Exitsing data, Update Please");
NSString *updateSQL = [NSString stringWithFormat:#"UPDATE EMPLOYEES set name = '%#', department = '%#', age = '%#' WHERE id = ?",
employee.name,
employee.department,
[NSString stringWithFormat:#"%d", employee.age]];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(mySqliteDB, update_stmt, -1, &statement, NULL );
sqlite3_bind_int(statement, 1, employee.employeeID);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
else{
NSLog(#"New data, Insert Please");
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO EMPLOYEES (name, department, age) VALUES (\"%#\", \"%#\", \"%#\")",
employee.name,
employee.department,
[NSString stringWithFormat:#"%d", employee.age]];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(mySqliteDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
success = true;
}
}
sqlite3_finalize(statement);
sqlite3_close(mySqliteDB);
}
return success;
}
I'm having an issue where I execute my app, I get the following warning:
"Incompatible pointer types passing 'const char *' to parameter of type 'sqlite3_stmt *' (aka 'struct sqlite3_stmt *')".
It only happens on the following lines:
if (sqlite3_prepare_v2(database, sql, -1, &databasePath, NULL)!=SQLITE_OK)
while (sqlite3_step(sql) == SQLITE_ROW)
szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sql, 0)];
szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sql, 1)];
sqlite3_finalize(sql);
Here is the function:
-(IBAction)setInput:(id)sender
{
NSString *strStoreNumber;
NSString *strRegNumber;
strStoreNumber = StoreNumber.text;
strRegNumber = RegNumber.text;
lblStoreNumber.text = strStoreNumber;
lblRegNumber.text = strRegNumber;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
// NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:#"tblStore.sqlite"];
NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"Opened sqlite database at %#", databasePath);
//...stuff
}
else
{
NSLog(#"Failed to open database at %# with error %s", databasePath, sqlite3_errmsg(database));
sqlite3_close (database);
}
NSString *querystring;
// create your statement
querystring = [NSString stringWithFormat:#"SELECT strStore FROM tblStore WHERE strStore = %#;", strStoreNumber];
const char *sql = [querystring UTF8String];
NSString *szStore = nil;
NSString *szReg = nil;
if (sqlite3_prepare_v2(database, sql, -1, &databasePath, NULL)!=SQLITE_OK) //queryString = Statement
{
NSLog(#"sql problem occured with: %s", sql);
NSLog(#"%s", sqlite3_errmsg(database));
}
else
{
// you could handle multiple rows here
while (sqlite3_step(databasePath) == SQLITE_ROW) // queryString = statement
{
szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(databasePath, 0)];
szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(databasePath, 1)];
} // while
}
sqlite3_finalize(databasePath);
// Do something with data...
}
Any help or insight would be greatly appreciated. Thanks!
The database path is passed instead a statement handle pointer. Replace
if (sqlite3_prepare_v2(database, sql, -1, &databasePath, NULL)!=SQLITE_OK)
with
sqlite3_stmt *statement = nil;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK)
and set the finalization line to
sqlite3_finalize(statement);
The documentation on sqlite3_prepare_v2 gives more details on this method.