2011-03-30 17 views
1

私はsqliteデータベースを利用したiPhoneアプリケーションを作成しています。私は自分のデータベースに1つのテーブルを持っています。最初はテーブルに行がありません。私は自分のiPhoneシミュレータを使って新しいレコードを挿入すると、そのレコードがデータベースに自動的に更新されるはずです。どのようにこれを可能にすることができましたか?誰でもこの問題を解決するために私を助けてください。iphoneシミュレータ経由でsqliteデータベースにデータを挿入

+ (void) getInitialDataToDisplay:(NSString *)dbPath 
{ 
    SQLAppDelegate *appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate]; 

    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) { 

     const char *sql = "select coffeeID, coffeeName from coffee"; 
     sqlite3_stmt *selectstmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

      while(sqlite3_step(selectstmt) == SQLITE_ROW) { 

       NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); 
       Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey]; 
       coffeeObj.coffeeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 

       coffeeObj.isDirty = NO; 

       [appDelegate.coffeeArray addObject:coffeeObj]; 
       [coffeeObj release]; 
      } 
     } 
    } 
    else 
     sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 
} 

+ (void) finalizeStatements 
{ 
    if (database) sqlite3_close(database); 
     if (deleteStmt) sqlite3_finalize(deleteStmt); 
      if (addStmt) sqlite3_finalize(addStmt); 
       if (detailStmt) sqlite3_finalize(detailStmt); 
        if (updateStmt) sqlite3_finalize(updateStmt); 
         } 

- (id) initWithPrimaryKey:(NSInteger) pk 
{ 
    [super init]; 
    coffeeID = pk; 

    coffeeImage = [[UIImage alloc] init]; 
    isDetailViewHydrated = NO; 

    return self; 
} 

- (void) deleteCoffee 
{ 
    if(deleteStmt == nil) { 
     const char *sql = "delete from Coffee where coffeeID = ?"; 
     if(sqlite3_prepare_v2(database, sql, -1, &deleteStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database)); 
      } 

    //When binding parameters, index starts from 1 and not zero. 
    sqlite3_bind_int(deleteStmt, 1, coffeeID); 

    if (SQLITE_DONE != sqlite3_step(deleteStmt)) 
     NSAssert1(0, @"Error while deleting. '%s'", sqlite3_errmsg(database)); 

     sqlite3_reset(deleteStmt); 
     } 

- (void) addCoffee 
{ 
    if(addStmt == nil) { 
     const char *sql = "insert into Coffee(CoffeeName, Price) Values(?, ?)"; 
     if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
      } 

    sqlite3_bind_text(addStmt, 1, [coffeeName UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_double(addStmt, 2, [price doubleValue]); 

    if(SQLITE_DONE != sqlite3_step(addStmt)) 
     NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
     else 
      //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid 
      coffeeID = sqlite3_last_insert_rowid(database); 

      //Reset the add statement. 
      sqlite3_reset(addStmt); 
      } 

- (void) hydrateDetailViewData 
{ 
    //If the detail view is hydrated then do not get it from the database. 
    if(isDetailViewHydrated) return; 

    if(detailStmt == nil) { 
     const char *sql = "Select price, CoffeeImage from Coffee Where CoffeeID = ?"; 
     if(sqlite3_prepare_v2(database, sql, -1, &detailStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating detail view statement. '%s'", sqlite3_errmsg(database)); 
      } 

    sqlite3_bind_int(detailStmt, 1, coffeeID); 

    if(SQLITE_DONE != sqlite3_step(detailStmt)) { 

     //Get the price in a temporary variable. 
     NSDecimalNumber *priceDN = [[NSDecimalNumber alloc] initWithDouble:sqlite3_column_double(detailStmt, 0)]; 

     //Assign the price. The price value will be copied, since the property is declared with "copy" attribute. 
     self.price = priceDN; 

     NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(detailStmt, 1) length:sqlite3_column_bytes(detailStmt, 1)]; 

     if(data == nil) 
      NSLog(@"No image found."); 
      else 
       self.coffeeImage = [UIImage imageWithData:data]; 

       //Release the temporary variable. Since we created it using alloc, we have own it. 
       [priceDN release]; 
    } 
    else 
     NSAssert1(0, @"Error while getting the price of coffee. '%s'", sqlite3_errmsg(database)); 

     //Reset the detail statement. 
     sqlite3_reset(detailStmt); 

     //Set isDetailViewHydrated as YES, so we do not get it again from the database. 
     isDetailViewHydrated = YES; 
     } 

- (void) saveAllData 
{ 
    if(isDirty) 
    { 
     if(updateStmt == nil) 
     { 
      const char *sql = "update Coffee Set CoffeeName = ?, Price = ?, CoffeeImage = ? Where CoffeeID = ?"; 
      if(sqlite3_prepare_v2(database, sql, -1, &updateStmt, NULL) != SQLITE_OK) 
       NSAssert1(0, @"Error while creating update statement. '%s'", sqlite3_errmsg(database)); 
       } 

     sqlite3_bind_text(updateStmt, 1, [coffeeName UTF8String], -1, SQLITE_TRANSIENT); 
     sqlite3_bind_double(updateStmt, 2, [price doubleValue]); 

     NSData *imgData = UIImagePNGRepresentation(self.coffeeImage); 

     int returnValue = -1; 
     if(self.coffeeImage != nil) 
      returnValue = sqlite3_bind_blob(updateStmt, 3, [imgData bytes], [imgData length], NULL); 
      else 
       returnValue = sqlite3_bind_blob(updateStmt, 3, nil, -1, NULL); 

       sqlite3_bind_int(updateStmt, 4, coffeeID); 

       if(returnValue != SQLITE_OK) 
        NSLog(@"Not OK!!!"); 

        if(SQLITE_DONE != sqlite3_step(updateStmt)) 
         NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(database)); 

         sqlite3_reset(updateStmt); 

         isDirty = NO; 
         } 

    //Reclaim all memory here. 
    [coffeeName release]; 
    coffeeName = nil; 
    [price release]; 
    price = nil; 

    isDetailViewHydrated = NO; 
} 

- (void)setCoffeeName:(NSString *)newValue 
{ 
    self.isDirty = YES; 
    [coffeeName release]; 
    coffeeName = [newValue copy]; 
} 

- (void)setPrice:(NSDecimalNumber *)newNumber 
{ 
    self.isDirty = YES; 
    [price release]; 
    price = [newNumber copy]; 
} 

- (void)setCoffeeImage:(UIImage *)theCoffeeImage 
{ 
    self.isDirty = YES; 
    [coffeeImage release]; 
    coffeeImage = [theCoffeeImage retain]; 
} 
+0

レコードをデータベースに更新したいと言うと、アプリ内のsqlite(同期の質問)、また​​は単にsqlite dbに行を挿入する際に問題がありますか? –

+0

sqlite dbに行を挿入する際に問題が発生しています。 – Rocky

+0

この問題の解決方法 – Rocky

答えて

0

この機能を使用すると、+(void) finalizeStatements;が表示され、DBをクローズして準備済みのクエリを確定します。 まず、この関数をどこからでも呼び出さないでください。とにかく、何らかの理由でこの関数を呼び出すと、fromのコードが正しくないことがあります。なぜなら、すべてのステートメントを最初にファイナライズし、その後に接続を閉じる必要があるからです。 のマニュアルを読むsqlite3_closesqlite3_finalizeのドキュメントを読む。ドキュメントの内容sqlite3_closeアプリケーションは[sqlite3_finalize |すべての[準備済みの文]および[sqlite3_blob_close |オブジェクトをクローズする前に[sqlite3]オブジェクトに関連付けられているすべての[BLOBハンドル]を閉じます。 これで問題が解決しない場合は、準備した各メソッドの最後に文を確定してみてください。 これがあなたを助けてくれることを願っています。

0

addCoffeeを試すときに、getInitialDataToDisplayで開いたデータベース変数が引き続き使用できるかどうかわかりません。あなたはその接続を閉じずにaddCoffeeの始めに新しいファイルを開きます(完了したら閉じます)

関連する問題