sqlite3_prepare_v2 failed (Xcode sqlite 3) - iphone

I'm so trying to connect the sqlite but can't. Can someone help me? I don't see any error here at all and I've searched high and low for this problem on google and here but I can't find any way to fix this.
I'm following the tutorial here
Do help me, I'm going crazy over this error. =(
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
sqlite3 *contactDB; //declare pointer to database structurery
const char *dbPath = [databasePath UTF8String]; //convert NSString to UTF8String
//open database file. TRUE = success, FALSE = failed
if (sqlite3_open(dbPath, &contactDB)== SQLITE_OK){
NSLog(#"Opened");
sqlite3_stmt *statement;
NSString *querySQL = #"SELECT address, phone FROM contacts";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(contactDB, query_stmt, 1, &statement, NULL) == SQLITE_OK) {
NSLog(#"Statement is OK");
}else{
NSLog(#"Statement FAILED");
}
}else{
NSLog(#"Failed");
}
The log only reads "Opened" then "Statement FAILED"

This is how I do it. (Compiled piece of my database class)
Shows you the sql error too.
sqlite3 *_database;
sqlite3_open([databasePath UTF8String], &_database);
NSString *sqlStatement = #"SELECT address, phone FROM contacts";
const char *sql = [sqlStatement UTF8String];
static sqlite3_stmt *compiledStatement;
int result = sqlite3_prepare_v2(_database, sql, -1, &compiledStatement, NULL);
if(result != SQLITE_OK) {
NSLog(#"Prepare-error #%i: %s", result, sqlite3_errmsg(_database));
}
result = sqlite3_step(compiledStatement);
if (result != SQLITE_DONE) {
NSLog(#"Step-error #%i for '%#': %s", result, sqlStatement, sqlite3_errmsg(_database));
}
sqlite3_finalize(compiledStatement);

The error is in this line of code.
if (sqlite3_prepare_v2(contactDB, query_stmt, 1, &statement, NULL) == SQLITE_OK) {
The 1 is wrong. From the SQLite docs:
int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
If the nByte argument is less than zero, then zSql is read up to the first zero
terminator. If nByte is non-negative, then it is the maximum number of bytes
read from zSql.
So you are forcing SQLite to only read the first byte from the statement. Of course this is invalid.

Make sure these points you have done in your project.
Verify the file is listed under "Copy Bundle Resources" under your Target's "Build Phases" and NOT under "Copy Files" with a custom destination or sub-path.
Make sure you don't have any path conflicts with your sqlite file.I mean document directory/database path/ are correct.
And I have implemented sqlite query like
SELECT * FROM someTable WHERE status LIKE 'someString' AND BankName LIKE 'someString'
Instead of
SELECT * FROM someTable WHERE status='someString' AND BankName='someString'
Make sure you have not included your sqlite file in any other application
Make sure you don't have duplicate sqlite files with same path.
This is worked for me after lot of struggle, I hope it helps some one. Please up vote if it helps.

Related

not getting inside while loop when selecting a single row from sqlite

I have a problem with sqlite, when i select a single row from table and then check sqlite3_step(statement) == SQLITE_ROW both values are different and not getting inside while statement.
This is the code:
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
//NSLog(#"working777.............%d",sqlite3_step(statement));
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"working888.............%d",SQLITE_ROW);
NSString *addressField = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)];
NSString *phoneField = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
NSLog(#"............statement...........addressField %#, phoneField %#",addressField,phoneField);
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
}
The proper way to create such a query would be like this:
NSString *querySQL = #"SELECT * FROM Major_Events WHERE temple_id = ?";
Then prepare the statement. I assume query_stmt is the char * value from querySQL.
Once the statement is prepared you then need to bind the value.
sqlite3_bind_int(statement, 1, temp_id); // bind is 1-based
Of course temp_id needs to be an int value and not a string. There are various sqlite3_bind_xxx statements for different data types. Use the appropriate one.
Once all of the query parameters are bound, you can execute the query using sqlite3_step.
The nice thing about this approach over string formats is that strings get properly escape and put in quotes for you. It's much harder to mess up and it makes your queries much safer against SQL injection attacks.
For many records:-
if (sqlite3_open([[self getDBPath] UTF8String], &database) == SQLITE_OK) {
const char *sql = "select * from Place";
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
}
sqlite3_finalize(selectstmt);
sqlite3_close(database);
}
}
else
{
sqlite3_close(database);
}
If you want a single record then change while to if
if(sqlite3_step(selectstmt) == SQLITE_ROW) {
rest everything will be same
I hope it helps and if your while loop is not getting executed then it means there is some problem with your query.You need to check that also.

Delete all the records in table in iphone sdk with sqlite3

EDITED:- This is what i had implements:-
- (void) Delete_LoginData {
sqlite3 *database;
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK)
{
const char *sql = "DELETE FROM Login";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL) == SQLITE_OK)
{
sqlite3_reset(statement);
}
}
}
I want to delete all the rows from the database in one click.I had implemented the below methods:-
- (void) Delete_LoginData {
sqlite3 *database;
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
const char *sql = "DELETE * FROM Login";
sqlite3_stmt *statement;
statement = [self PrepareStatement:sql];
// int a1 = sqlite3_bind_int(statement, 1, 1);
sqlite3_step(statement);
sqlite3_reset(statement);
}
}
-(sqlite3_stmt*) PrepareStatement:(const char *)sql{
// Setup the database object
sqlite3 *database;
// Init the animals Array
// Open the database from the users filessytem
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = sql;
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, NULL) == SQLITE_OK) {
//NSLog(#"COMPILED STATEMENT: %#",compiledStatement);
return compiledStatement;
}
}
return nil;
}
But it not working.
I am getting 0X0 for this statement = [self PrepareStatement:sql];
in delete_logindata method.
How to solve this.
Is there any solution regarding this?
write const char *sql = "DELETE FROM Login"; instead of const char *sql = "DELETE * FROM Login";
change your const char*sql
const char *sql = "DELETE * FROM Login";
change above with this
const char *sql = "DELETE FROM Login";
Please change your method like:
- (void) Delete_LoginData
{
sqlite3 *database;
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK)
{
const char *sql = "DELETE FROM Login";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL) == SQLITE_OK)
{
sqlite3_step(statement);
}
}
}
In your code you are opening the database twice. In the second method you are opening a database that was already opened !
I don't know it is the actual issue or not, but I'll suggest don't do this.
I dont know what will be correct answer for it.
But I can suggest u this link http://klanguedoc.hubpages.com/hub/IOS-5-SDK-Database-Insert-Update-Delete-with-SQLite-and-Objective-C-C-How-To may be it will help u.

Iphone/ipad : I got "a file is encrypted or is not a database" error while using the pragma key in sqlite cipher?

I am using ios5.0 and Xcode 4.2 and sqlite 3. I can create the database and table and also I can read and write in table.
But If i use the sqlcipher , then I got the error "a file is encrypted or is not a database" .
Please explain me, why i am getting these kind of error ?. I have attached the code with this. Please find it.. and THanks in advance.
-(void) readFromDatabase {
// Setup the database object
sqlite3 *database;
devicesArray = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from patient;";
sqlite3_stmt *compiledStatement;
// const char* key = [#"test" UTF8String];
// NSLog(#"Length %lu" , strlen(key));
// sqlite3_key(database, key, strlen(key));
sqlite3_exec(database, "PRAGMA KEY='test123';", NULL, NULL, NULL);
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database) );
int returnCode = sqlite3_exec(database, (const char*) "SELECT count(*) FROM patient;", NULL, NULL, NULL);
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database) );
NSLog(#"%d",returnCode); // the return code is 26 and getting the error
if (sqlite3_exec(database, (const char*) "SELECT count(*) FROM patient;", NULL, NULL, NULL) == SQLITE_OK) {
NSLog(#"Success");
} else {
NSLog(#"Failure");
}
returnCode = sqlite3_prepare_v2( database, sqlStatement, -1, &compiledStatement, nil);
printf( "could not prepare statemnt1: %s\n", sqlite3_errmsg(database) );
NSLog(#"%d",returnCode); //the return code is 26 and getting the error
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
devices *d = [[devices alloc] initWithName:aName description:aDescription url:aImageUrl];
[devicesArray addObject:d];
[devices release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
Your code seems to be assuming that the database already exists. Are you trying to open an existing, non-encrypted database and then encrypt it using SQLCipher? If so, what you are doing will not work.
The sqlite3_key function does not encrypt an existing database. If you want to encrypt an existing database you'd either need to ATTACH a new encrypted database and move data between the two, as described here:
http://zetetic.net/blog/2009/12/29/how-to-encrypt-a-plaintext-sqlite-database-to-use-sqlcipher/
Or, using the SQLCipher 2 you can use sqlcipher_export which provides an easy way to move data between databases.:
http://groups.google.com/group/sqlcipher/msg/76d5b03426419761

Problems storing data in iPhone SQLite help!

I just started looking into SQLite for the iPhone SDK. I have been looking at this tutorial and I am wondering how can I find an ID and store the information in that field of the ID? (the tutorial increments an ID every time I press save).
Also, how can I loop though the whole database e.g., add all the id numbers up? Is there a command?
Not much changes in the database access in the methods. Only the SQLite query changes. It should be something on these lines.
- (NSInteger) sumOfIds
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
NSString *result;
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *querySQL = #"SELECT sum(id) FROM contacts";
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 *result = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
}
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
}
return [result floatValue];
}

SQL delete doesn't seem to be working

Help please :-)
Following code is supposed to delete a record. It seems to execute OK, no error message and the NSLog shows "Record Deleted" message. However the record is not deleted. I have used Terminal to check and indeed the deleted record is still there. The puzzling part is that I have very similar code to add and count records and they all seem to work... I am not an SQL expert, so I am hoping that an expert in this crowd can see the error.
Thanks
(void) deleteRecord
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &wfDataBase) == SQLITE_OK)
{
NSLog(#"About to Delete Record %d",currentID);
NSString *querySQL = [NSString stringWithFormat: #"DELETE from wfDataBase WHERE ID = %d", currentID];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(wfDataBase, query_stmt, -1, &statement, NULL) == SQLITE_OK)
l_status.text = #"Record Deleted";
else
l_status.text = #"Can't Delete";
sqlite3_finalize(statement);
sqlite3_close(wfDataBase);
}
}
Are you sure you have evaluated (sqlite3_step(statement )) the compiled statement (sqlite3_prepare_v2(wfDataBase, query_stmt, -1, &statement, NULL)) before destroying it (sqlite3_finalize(statement))?
Note: I'm not an expert on SQLite (indeed I don't know anything about SQLite) but I guess this is the cause of the problem.