2013-05-22 1 views
1

Я пытаюсь сохранить строки в базе данных SQLite для приложения iPhone iOS 6. Это довольно просто: шутка отображается в текстовом виде при нажатии кнопки. При нажатии второй кнопки я хочу сохранить этот текст в базе данных SQLite (saveJoke). Однако SQLITE_DONE никогда не возвращается, указывая, что это не работает. Итак, глядя на мои предупреждения, я всегда получаю «Fail», когда saveJoke выполняется ниже.Не удается сохранить строку в базе данных SQLite (SQLITE_DONE не возвращает true)

Любая идея, почему это не работает? У меня есть ощущение, что я могу пропустить что-то основное в создании и вставке в базу данных SQLite. Очень благодарен за помощь!

Мой код:

JokeFirstViewController.m:

#import "JokeFirstViewController.h" 

@interface JokeFirstViewController() 

@end 

@implementation JokeFirstViewController 

@synthesize joke = _joke; 

- (void)viewDidLoad 
    { 
    [super viewDidLoad]; 

    NSString *docsDir; 
    NSArray *dirPaths; 

    dirPaths = NSSearchPathForDirectoriesInDomains(
               NSDocumentDirectory, NSUserDomainMask, YES); 

    docsDir = dirPaths[0]; 

    // Build the path to the database file 
    _databasePath = [[NSString alloc] 
       initWithString: [docsDir stringByAppendingPathComponent: 
            @"contacts.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, JOKESAVED TEXT)"; //look into 

     sqlite3_close(_contactDB); 

    } 
    } 
} 

- (IBAction)saveJoke:(id)sender { 

    /* get current joke displayed */ 
    self.joke = self.text.text; 
    NSString *currentJoke = self.joke; 
    NSString *jokeSaved = [[NSString alloc] initWithFormat:currentJoke]; 

    sqlite3_stmt *statement; 
    const char *dbpath = [_databasePath UTF8String]; 

    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) 
    { 

     NSString *insertSQL = [NSString stringWithFormat: 
           @"INSERT INTO CONTACTS (jokesaved) VALUES (?)", 
           jokeSaved]; 

     const char *insert_stmt = [insertSQL UTF8String]; 
     sqlite3_prepare_v2(_contactDB, insert_stmt, 
          -1, &statement, NULL); 
     if (sqlite3_step(statement) == SQLITE_DONE) 
     { 
      void AlertWithMessage(NSString *message); 
      { 
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Database" message:@"Success" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
       [alert show]; 
      } 
     } else { 
      void AlertWithMessage(NSString *message); 
      { 
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Database" message:@"Fail" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
       [alert show]; 
      } 

     } 
     sqlite3_finalize(statement); 
     sqlite3_close(_contactDB); 
    } 

    } 

} 

JokeFirstViewController.h:

#import <UIKit/UIKit.h> 
#import <MessageUI/MFMessageComposeViewController.h> 
#import <sqlite3.h> 

@interface JokeFirstViewController : UIViewController <MFMessageComposeViewControllerDelegate> 


- (IBAction)saveJoke:(id)sender; 

- (IBAction)shareJoke:(id)sender; 

- (IBAction)generateJoke:(id)sender; 

@property (strong, nonatomic) IBOutlet UITextView *text; 

@property (copy, nonatomic) NSString *joke; 

@property (strong, nonatomic) NSString *databasePath; 

@property (nonatomic) sqlite3 *contactDB; 

@end 
+0

уже вы поняли, что вы не используете создать таблицу предложение? – tkanzakic

+0

Вы должны проверить результат 'sqlite3_prepare_v2' и убедиться, что это' SQLITE_OK'. А если нет, посмотрите на 'sqlite3_errmsg()', чтобы получить хорошее объяснение, почему это не удалось. – Rob

+0

Но, tkanzanic прав, вы действительно должны «sqlite3_exec», которые создают таблицу SQL, если вы хотите, чтобы она создала таблицу. И вы действительно должны всегда проверять коды результатов для всех вызовов функций 'sqlite3', и если они терпят неудачу, выполните' NSLog (@ "% s:% s", __FUNCTION__, sqlite3_errmsg (contactDB)); ' – Rob

ответ

1

Вы должны также проверить запрос INSERT, ваш StringFormat неправильно:

Изменить:

NSString *insertSQL = [NSString stringWithFormat: 
           @"INSERT INTO CONTACTS (jokesaved) VALUES (?)", jokeSaved]; 

к:

NSString *insertSQL = [NSString stringWithFormat: 
           @"INSERT INTO CONTACTS (jokesaved) VALUES ('%@')", jokeSaved]; 
1
if (insert_statement == nil) 
{ 
    const char * sql = "INSERT INTO CONTACTS (jokesaved) VALUES (?)"; 
    if (sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL) != SQLITE_OK) 
    { 
     NSAssert1(0, @"Error: Failed to prepare SQL statement: %s.",sqlite3_errmsg(database)); 
    } 
} 
@try 
{ 
    sqlite3_bind_text (insert_statement, 1, [jokesSaved UTF8String], -1, SQLITE_TRANSIENT); 
} 
@catch (NSException *exception) 
{ 
    ; 
} 
int val = sqlite3_step(insert_statement); 
if (val != SQLITE_DONE) 
{ 
    NSAssert1(0, @"Failed to prepare SQL property insert statement: %s.", sqlite3_errmsg(database)); 
} 
else 
{ 

} 
+0

У вас есть полный рабочий пример? Имея некоторые проблемы, поставив это в контексте моего кода выше. – user1854291

+0

Почему вы завершаете вызов 'sqlite3_bind_text' в блоке' try/catch'? В этом нет необходимости. – rmaddy

Смежные вопросы