2016-05-06 4 views
0

sqliteデータベースからデータを選択しています。問題は、次のコードを使用すると、しばらく時間がかかることです。しかし、他のテーブルに対してこのメ​​ソッドを2回呼び出すと、他のメソッドにはnull selectステートメントが表示されます。メソッド内で何か間違っているので、他のテーブルで同じものを使用するとしばらく時間がかかります。sqliteからデータを選択するiOSにnull文があります

-(void)getAssessmentNumber:(NSString *)dbPath{ 
    appDelegate=[[UIApplication sharedApplication]delegate]; 
    NSString*fileDBPath=[[NSBundle mainBundle] pathForResource:@"Database" ofType:@"sqlite"]; 
    if (sqlite3_open([fileDBPath UTF8String], &database) == SQLITE_OK) 
    { 
     // NSLog(@"%@",[self getDBPath]); 
     NSString *querySQL = [NSString stringWithFormat:@"Select Am.AssessmentID , Am.AssessmentName From AssessmentMaster Am LEFT JOIN AssessmentDepartmentMapping M ON M.AssessmentID = Am.AssessmentID LEFT JOIN DepartmentListing d ON d.departmentID =M.departmentID where d.departmentID = '%@'",appDelegate.departmentID]; 
     NSLog(@"%@",querySQL); 
     const char *sql = [querySQL UTF8String]; 
     sqlite3_stmt *selectstmt; 
     NSError *error; 
     [appDelegate.assessmentNumberArray removeAllObjects]; 

     if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 
     { 
      while (sqlite3_step(selectstmt) == SQLITE_ROW) 
      { 
       NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); 
       AssessmentListening *asmObj = [[AssessmentListening alloc] initWithPrimaryKey:primaryKey]; 
       asmObj.assessmentID=[NSString stringWithFormat:@"%d",primaryKey]; 

       asmObj.assessmentName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 

       [appDelegate.assessmentNumberArray addObject:asmObj]; 
      } 
     } 
     else { 
      NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
     } 

     // sqlite3_finalize(selectstmt); 
    } 
    sqlite3_close(database); 
} 

は、テーブルからデータを取得するため、この罰金ですか?

+0

私はquerySQLがなくなると言っていますか? –

+0

@TejaNandamuri sqlite3_stmt selectstmtがnullになっている理由はsqlite_step3ではない –

+0

なぜ 'sqlite3_prepare_v2'を2回呼び出すのですか?ただ一度それを呼んでください。なぜあなたは文を準備できないときにデータベースを作成できなかったというエラーをログに記録しますか? – rmaddy

答えて

1

コードを少し修正する必要があります。

- (void)getAssessmentNumber:(NSString *)dbPath { 
    NSString *fileDBPath = [[NSBundle mainBundle] pathForResource:@"Database" ofType:@"sqlite"]; 
    if (sqlite3_open([fileDBPath UTF8String], &database) == SQLITE_OK) { 
     appDelegate = [[UIApplication sharedApplication] delegate]; 
     [appDelegate.assessmentNumberArray removeAllObjects]; 

     const char *sql = "Select Am.AssessmentID, Am.AssessmentName From AssessmentMaster Am LEFT JOIN AssessmentDepartmentMapping M ON M.AssessmentID = Am.AssessmentID LEFT JOIN DepartmentListing d ON d.departmentID = M.departmentID where d.departmentID = ?"; 
     sqlite3_stmt *selectstmt; 

     if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 
      sqlite3_bind_text(selectstmt, 0, [appDelegate.departmentID UTF8String], -1, SQLITE_TRANSIENT); 

      while (sqlite3_step(selectstmt) == SQLITE_ROW) { 
       NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); 
       AssessmentListening *asmObj = [[AssessmentListening alloc] initWithPrimaryKey:primaryKey]; 
       asmObj.assessmentID = [NSString stringWithFormat:@"%d", primaryKey]; 

       asmObj.assessmentName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 

       [appDelegate.assessmentNumberArray addObject:asmObj]; 
      } 

      sqlite3_finalize(selectstmt); 
     } else { 
      NSLog(@"Unable to prepare statement: %s", sqlite3_errmsg(database)); 
     } 

     sqlite3_close(database); 
    } else { 
     NSLog(@"Unable to open the database from %@: %s", fileDBPath, sqlite3_errmsg(database); 
    } 
} 

注すべての変更:それが開いている場合

  1. のみデータベースを閉じます。
  2. 文が準備されている場合にのみ、文を確定します。
  3. stringWithFormatでクエリを作成しないでください。クエリに値をバインドするには、適切なsqlite3_bind_xxx関数を使用します。これにより、特殊文字がエスケープされ、引用符が適切に処理されます。
  4. 適切なエラーチェックを使用してください。エラーを表示するには、sqlite3_errmsgを使用してください。
+0

これを試してみてください。 –

+0

アプリ全体で使用している場合は、このようにデータパスを設定する必要があります。または、ドキュメントディレクトリ –

+0

にデータベースをコピーする必要があります。アプリケーションバンドルでは読み取り専用です。これまでにデータベースに書き込む必要がある場合は、まずDocumentsフォルダにコピーしてから、Documentsフォルダ内のデータベースを開く必要があります。 – rmaddy

関連する問題