2013-05-03 37 views
2

我跟着一篇關於創建SQLite數據庫,存儲內容並找到它的教程。 我沒有做的是創建接口,因爲控制檯日誌記錄可以更快。 (這也並不需要其他人來構建interace,但不要忘記導入庫:)!)在ios上的SQLite數據庫中找到條目

這是教程櫃面它的問題: http://www.techotopia.com/index.php/An_Example_SQLite_based_iOS_6_iPhone_Application

我有發現數據的問題,是否有人知道它可能是什麼?

- (void) findContact { 
    const char *dbpath = [_databasePath UTF8String]; 
    sqlite3_stmt *statement; 

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

     NSString *querySQL = [NSString stringWithFormat: 
           @"SELECT adress, phone FROM contacts WHERE name=\"%@\"", @"DoekeW"]; 

     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 *adressField = [[NSString alloc] initWithUTF8String: 
             (const char*) sqlite3_column_text(statement, 0)]; 
       NSString *phoneField = [[NSString alloc] initWithUTF8String: 
             (const char*) sqlite3_column_text(statement, 1)]; 
       NSLog(@"adressField: %@ phoneField: %@", adressField, phoneField); 
      } 
      else { 
       NSLog(@"no match"); 
      } 
      sqlite3_finalize(statement); 
     } 
     else { 
      // 1, whatever that is 
      NSLog(@"hmm %d", sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL)); 
     } 
     sqlite3_close(_contactDB); 
    } 
} 

這裏是完整的代碼:

.h文件中:

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

@interface IGViewController : UIViewController 

@property (strong, nonatomic) NSString *databasePath; 
@property (nonatomic) sqlite3 *contactDB; 

@end 

.m文件

#import "IGViewController.h" 

@interface IGViewController() 

@end 

@implementation IGViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    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:@"contacts.db"]]; 

    NSLog(@"%@", _databasePath); 

    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"; 
       NSLog(@"Failed to create table"); 

      } 
      sqlite3_close(_contactDB); 
     } else { 
      // _status.text = @"Failed to open/create database"; 
      NSLog(@"Failed to open/create database"); 
     } 
    } 

    else { 
     NSLog(@"database allready existed"); 
    } 

    [self saveData]; 

    [self findContact]; 
} 


- (void) saveData { 
    sqlite3_stmt *statement; 
    const char *dbpath = [_databasePath UTF8String]; 

    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) { 
     NSString *insertSQL = [NSString stringWithFormat: 
           @"INSERT INTO CONTACTS (name, address, phone) VALUES (\"%@\", \"%@\", \"%@\")", 
           @"DoekeW", @"Molenstraat", @"483577"]; 

     const char *insert_stmt = [insertSQL UTF8String]; 
     sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL); 
     if(sqlite3_step(statement) == SQLITE_DONE) { 
      NSLog(@"saved data!"); 
     } 
     else { 
      NSLog(@"something wrong, no data saved"); 
     } 
     sqlite3_finalize(statement); 
     sqlite3_close(_contactDB); 
    } 
} 

- (void) findContact { 
    const char *dbpath = [_databasePath UTF8String]; 
    sqlite3_stmt *statement; 

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

     NSString *querySQL = [NSString stringWithFormat: 
           @"SELECT adress, phone FROM contacts WHERE name=\"%@\"", @"DoekeW"]; 

     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 *adressField = [[NSString alloc] initWithUTF8String: 
             (const char*) sqlite3_column_text(statement, 0)]; 
       NSString *phoneField = [[NSString alloc] initWithUTF8String: 
             (const char*) sqlite3_column_text(statement, 1)]; 
       NSLog(@"adressField: %@ phoneField: %@", adressField, phoneField); 
      } 
      else { 
       NSLog(@"no match"); 
      } 
      sqlite3_finalize(statement); 
     } 
     else { 
      // 1, whatever that is 
      NSLog(@"hmm %d", sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL)); 
     } 
     sqlite3_close(_contactDB); 
    } 
} 



- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 
+0

我建議你嘗試FMDB,它更容易使用SQLite工作,他們有的CocoaPods podspec,這樣的設置將會是輕而易舉的。一個很好的[使用FMDB的教程](http://www.highoncoding.com/Articles/836_Persisting_iOS_Application_Data_in_SQLite_Database_Using_FMDB.aspx) – Anupdas 2013-05-03 14:28:47

回答

0

您在findContact,說有一個NSLog聲明:

NSLog(@"hmm %d", sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL)); 

你絕對不想在失敗時再次做準備。你只是想檢索錯誤信息。因此,它應該是:

NSLog(@"prepare failed: %s", sqlite3_errmsg(_contactDB)); 

如果你這樣做,你會收到在SQL語句中指出的address拼寫錯誤的錯誤消息。

坦率地說,幾乎所有的SQLite調用應檢查其結果和(爲sqlite3_stepSQLITE_ROWSQLITE_DONE)如果沒有SQLITE_OK應,報告sqlite3_errmsg

當你採用sqlite3_errmsg時,你會發現你的錯誤要快得多。讓SQLite精確地告訴你問題是什麼!


順便說一句,我也建議:

  1. 我也勸你曾經對構建SQL語句stringWithFormat。如果個人的名字是Dwayne "The Rock" Johnson,那麼您會遇到問題。相反,您應該使用?佔位符。 (你也將會是容易受到SQL注入攻擊。)底線,而不是:

    NSString *insertSQL = [NSString stringWithFormat: 
             @"INSERT INTO CONTACTS (name, address, phone) VALUES (\"%@\", \"%@\", \"%@\")", 
             @"DoekeW", @"Molenstraat", @"483577"]; 
    
    const char *insert_stmt = [insertSQL UTF8String]; 
    sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL); 
    if(sqlite3_step(statement) == SQLITE_DONE) { 
        NSLog(@"saved data!"); 
    } 
    else { 
        NSLog(@"something wrong, no data saved"); 
    } 
    sqlite3_finalize(statement); 
    

    你應該使用:

    const char *insert_stmt = "INSERT INTO CONTACTS (name, address, phone) VALUES (?, ?, ?)"; 
    
    if (sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK) 
        NSLog(@"%s: prepare error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB)); 
    
    if (sqlite3_bind_text(statement, 1, [@"DoekeW" UTF8String], -1, NULL) != SQLITE_OK) 
        NSLog(@"%s: bind 1 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB)); 
    
    if (sqlite3_bind_text(statement, 2, [@"Molenstraat" UTF8String], -1, NULL) != SQLITE_OK) 
        NSLog(@"%s: bind 2 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB)); 
    
    if (sqlite3_bind_text(statement, 3, [@"483577" UTF8String], -1, NULL) != SQLITE_OK) 
        NSLog(@"%s: bind 3 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB)); 
    
    if(sqlite3_step(statement) == SQLITE_DONE) { 
        NSLog(@"saved data!"); 
    } 
    else { 
        NSLog(@"%s: step error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB)); 
    } 
    
    sqlite3_finalize(statement); 
    

    基本上,使用sqlite3_bind_text到值綁定到這些?佔位符和消除一共stringWithFormatSELECT聲明的WHERE子句也是如此。

  2. 我第二次Anupdas的建議使用FMDB。它使SQLite編碼更容易。

相關問題