2013-05-22 61 views
1

我想將字符串存儲在iOS 6 iPhone應用程序的SQLite數據庫中。這很簡單:單擊按鈕時,在文本視圖中顯示一個笑話。當單擊第二個按鈕時,我想將該文本視圖保存到SQLite數據庫(saveJoke)中。但是,SQLITE_DONE永遠不會返回,表明這不起作用。所以,看着我的警報,當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

你也來檢查插入查詢,您的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

你爲什麼要在'try/catch'塊中調用'sqlite3_bind_text'?這是沒有必要的。 – rmaddy

相關問題