2011-09-25 40 views
2

我試圖做一個應用程序,從SQLite3數據庫讀取。我計劃在開發過程中預加載的數據,因此應用程序不需要任何修改在數據庫中,只有從中讀取,使查詢等sqlite iPhone閱讀數據的最佳做法

什麼是純粹讀取數據的最佳做法?我應該打開數據庫,讀取數據,並關閉它,每個查詢?該應用程序將進行許多小型查詢和一些大型的查詢。在應用程序的持續時間內打開數據庫還是更好,或者每次獲取都打開/關閉數據庫?

+0

找到任何其它提示? – bryanmac

回答

0

使用sqlite_open_v2SQLITE_OPEN_READONLY標誌。例如,我使用以下方法打開僅用於讀取的數據庫。

// Open for reading only. 
- (int) openDatabaseAtPath:(NSString *) path 
{ 
    if (database != nil) 
    { 
     sqlite3_close(self.database); 
     [self setDatabase:nil]; 
    } 

    int errorCode = SQLITE_OK; 
    errorCode = sqlite3_open_v2([path UTF8String], 
           &database, 
           SQLITE_OPEN_READONLY, 
           NULL); 

    return errorCode; 
} 
0

除非將數據庫複製到Documents目錄,否則您將使用資源目錄中的數據庫,並且該目錄只讀。

1

閱讀:

1.查詢,重要的是要重新使用編譯語句。
2.請確保您使用參數,以便您可以重新使用這些編譯查詢

當你調用sqlite3_prepare_v2,它編譯語句,讓您的語句返回參考。找到一種方法來保存並重新使用它。 *代碼見下面的代碼。您通過&聲明進行準備。

另外,請注意使用?參數。如果要重新使用該語句,則重新調用sqlite3_reset()語句,重新綁定來自程序(參數)的輸入並再次執行它。

sqlite3_stmt *statement; 
NSString *querySQL = @"update contacts set name=?,address=?,phone=? where id=?"; 
NSLog(@"query: %@", querySQL); 
const char *query_stmt = [querySQL UTF8String]; 

// preparing a query compiles the query so it can be re-used. 
// find a way to save off the *statement so you can re-use it. 
sqlite3_prepare_v2(_contactDb, query_stmt, -1, &statement, NULL); 

// use sqlite3_bind_xxx functions to bind in order values to the params 
sqlite3_bind_text(statement, 1, [[contact name] UTF8String], -1, SQLITE_STATIC); 
sqlite3_bind_text(statement, 2, [[contact address] UTF8String], -1, SQLITE_STATIC); 
sqlite3_bind_text(statement, 3, [[contact phone] UTF8String], -1, SQLITE_STATIC); 
sqlite3_bind_int64(statement, 4, [[contact id] longLongValue]); 

總是檢查返回碼!並記錄或處理錯誤。

rc = sqlite3_step(stmt); 
    switch (rc) 
    { 
     case SQLITE_ROW: 
      // ... 
      break; 

     case SQLITE_OK: 
     case SQLITE_DONE: 
      break; 

     default: 
      // .... 
      } 

      return NO; 
    } 

,如果你得到一個錯誤,請登錄或獲取eror消息提供更多信息:

- (NSString*)errorMessage 
{ 
    return [NSString stringWithCString:sqlite3_errmsg(_sqlite3) encoding:NSUTF8StringEncoding];  
} 
0

當您打開使用sqlite_open_v2SQLITE_OPEN_READONLY標誌數據庫時,SQLite打開的文件本身只讀模式,所以即使您的應用程序由於錯誤而損壞了屬於SQLite的內存,數據庫也將保持不變。

考慮到這一點,我會保持打開數據庫,直到應用程序退出。 (您不妨將其關閉,如果你收到了低內存的通知,並重新打開它的需求,但打開和關閉它的每個查詢,將是浪費。)

0

按照你的問題,你想讀取數據庫中的數據。所以下面是你的問題的答案。

  1. 沒有必要當你火查詢每次分貝打開。只有一次。如果你創建單例類並且在初始化時第一次打開它,那會更好。
  2. 使用下面的代碼方法,它將適用於所有具有條件選擇,分組等等的查詢。
  3. I)它需要輸出/結果列名作爲輸入陣列ⅱ)表名III)其中條件ⅳ)排序依據子句v)的基團通過子句

- (NSMutableArray *)runSelecteQueryForColumns: (NSArray *)p_columns ontableName: (NSString *)p_tableName withWhereClause: (NSString *)p_whereClause withOrderByClause: (NSString *)p_orederByCalause withGroupByClause: (NSString *)p_groupByClause 
{ 


    NSMutableArray *l_resultArray = [[NSMutableArray alloc] init]; 

    if(!self.m_database) 
    { 
     if(![self openDatabase]) 
     { 
      sqlite3_close(self.m_database); 
      //NSLog(@"error in select : DB creating : %@",p_whereClause); 
      return nil; 

     } 
    } 

    NSMutableString *l_simpleQuery =[[NSMutableString alloc] initWithString:@"Select"] ; 

    if(p_columns) 
    { 

     for(int l_row = 0 ; l_row < [p_columns count] ; l_row++) 
     { 
      if(l_row != [p_columns count]-1) 
      { 
       [l_simpleQuery appendString:[NSString stringWithFormat:@" %@,", [p_columns objectAtIndex:l_row]]]; 
      } 
      else 
      { 
       [l_simpleQuery appendString:[NSString stringWithFormat:@" %@", [p_columns objectAtIndex:l_row]]]; 
      } 
     } 
    } 
    else 
    { 
     [l_simpleQuery appendString:@" *"]; 
    } 

    [l_simpleQuery appendString:[NSString stringWithFormat:@" From %@",p_tableName]]; 

    if(p_whereClause) 
    { 
     [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_whereClause]]; 
    } 
    if(p_groupByCaluase) 
    { 
     [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_groupByCaluase]]; 
    } 

    if(p_orederByCalause) 
    { 
     [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_orederByCalause]]; 
    } 


    //NSLog(@"Select Query: - %@",l_simpleQuery); 

    const char *l_query_stmt = [l_simpleQuery UTF8String]; 

    sqlite3_stmt *l_statement = nil; 

    int i = sqlite3_prepare_v2(self.m_database, 
           l_query_stmt, -1, &l_statement, NULL); 

    if (i == SQLITE_OK) 
    { 

     while(sqlite3_step(l_statement) == SQLITE_ROW) 
     { 

      [l_resultArray addObject:[self createDictionary:l_statement]]; 

     } 

     sqlite3_finalize(l_statement); 


    } 
    else 
    { 
     sqlite3_finalize(l_statement); 
     //sqlite3_close(l_database); 
     DDLogError(@"%@ - error in SQL :%@",THIS_FILE,l_simpleQuery); 
     return nil; 
    } 
    //NSLog(@"RESULT %@",l_resultArray); 
    return l_resultArray; 

}