2011-03-10 115 views
0

我已經完全放棄了這一點,所以如果主持人恰巧來了,刪除會很好。
把這個問題留下來並沒有什麼壞處,但是CoreData更好,你知道嗎?sqlite3 int問題


我有一個sqlite數據庫來處理表的內容。這是偉大的一切(比我看到的其他選項更容易),但我在整數方面遇到了問題。在啓動應用程序後第一次編輯項目時,int的字段爲空。重新輸入工作正常,它會保存並出現在表格中,但下一次編輯(不重新打開應用程序)會將第二個項目的int設置爲第一個項目的int。

即,A(1)重置爲A(0)。我修復它(A(1)),但是一旦我加載編輯視圖,B(2)就變成B(1)。修正它(B(2))或不(B(1)),C(3)將與B具有相同(#)。

我仍然無法弄清楚是什麼原因造成的。將int更改爲一個字符串(編輯數據庫列和應用程序中的每個相關文件)肯定會起作用,但這樣做只是爲了讓它變得更慢,更容易中斷,這是一大堆不必要的工作。

編輯:

CREATE TABLE "items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" VARCHAR, "need" INTEGER DEFAULT 0, "notes" TEXT)

- (void)updateItemAtIndexPath:(NSIndexPath *)path { 
    Item *i = (Item *)[items objectAtIndex:path.row]; 
    int ret; 
    const char *sql = "update items set name = ?, need = ?, notes = ? where id = ?;"; 

    if (!updStmt) { // build update statement 
     if ((ret = sqlite3_prepare_v2(database, sql, -1, &updStmt, NULL)) != SQLITE_OK) { 
      NSAssert1(0, @"Error building statement to update items [%s]", sqlite3_errmsg(database)); 
     } 
    } 

    // bind values to statement 
    NSString *s = i.name; 
    if (s == NULL) s = @""; 
    sqlite3_bind_text(updStmt, 1, [s UTF8String], -1, SQLITE_TRANSIENT); 
    NSInteger n = i.need; 
    sqlite3_bind_int(updStmt, 2, n); 
    s = i.notes; 
    if (s == NULL) s = @""; 
    sqlite3_bind_text(updStmt, 3, [s UTF8String], -1, SQLITE_TRANSIENT); 
    n = i.itemid; 
    sqlite3_bind_int(updStmt, 4, n); 

    // now execute sql statement 
    if (sqlite3_step(updStmt) != SQLITE_DONE) { 
     NSAssert1(0, @"Error updating values [%s]", sqlite3_errmsg(database)); 
    } 

    // now reset bound statement to original state 
    sqlite3_reset(updStmt); 
} 

- (void)insertItem:(Item *)item { 
    int ret; 
    const char *sql = "insert into items (name, need, notes) values (?, ?, ?);"; 

    if (!insStmt) { // first insert - build statement 
     if ((ret = sqlite3_prepare_v2(database, sql, -1, &insStmt, NULL)) != SQLITE_OK) { 
      NSAssert1(0, @"Error building statement to insert item [%s]", sqlite3_errmsg(database)); 
     } 
    } 

    // bind values 
    NSString *s = item.name; 
    if (s == NULL) s = @""; 
    sqlite3_bind_text(insStmt, 1, [s UTF8String], -1, SQLITE_TRANSIENT); 
    NSInteger n = item.need; 
    sqlite3_bind_int(insStmt, 2, n); 
    s = item.notes; 
    if (s == NULL) s = @""; 
    sqlite3_bind_text(insStmt, 3, [s UTF8String], -1, SQLITE_TRANSIENT); 

    // execute sql statement 
    if (sqlite3_step(insStmt) != SQLITE_DONE) { 
     NSAssert1(0, @"Error inserting item [%s]", sqlite3_errmsg(database)); 
    } 

    // reset bound statement to original state 
    sqlite3_reset(insStmt); 

    [self readItems]; // refresh array 
} 
+0

有些代碼可能被要求解決這個問題,以及表定義。問題本身可能不在SQLite中。 – MPelletier 2011-03-10 15:52:11

+0

我有點想,但我不知道該怎麼忍受。粘貼一切似乎有點愚蠢,但也許我應該... – Thromordyn 2011-03-10 15:55:03

+0

從表定義和更新例程開始。 – MPelletier 2011-03-10 15:55:44

回答

1

而不是使用sqlite3_bind_textsqlite3_bind_int的,我會嘗試從不同的價值觀構建的查詢字符串,並使用sqlite3_exec運行它。我們稱之爲解決方案的嘗試。

例(警告,未經測試!):

- (void)updateItemAtIndexPath:(NSIndexPath *)path { 
    Item *i = (Item *)[items objectAtIndex:path.row]; 

    // validate values 
    NSString *name = i.name; 
    if (name == NULL) name = @""; 
    [name stringByReplacingOccurrencesOfString:@"'" 
            withString:@"''"]; 
    NSInteger need = i.need; 
    NSString *notes = i.notes; 
    if (notes == NULL) notes = @""; 
    [notes stringByReplacingOccurrencesOfString:@"'" 
            withString:@"''"]; 
    NSInteger itemid = i.itemid; 

    NSString *sql = [NSString stringWithFormat: 
        @"update items set name = '%@', need = %@, notes = '%@' where id = %@;", 
        name, need, notes, itemid]; 

    // now execute sql statement 
    if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, NULL) != SQLITE_DONE) { 
     NSAssert1(0, @"Error updating values [%s]", sqlite3_errmsg(database)); 
    } 
} 
+0

我實際上並不知道如何做到這一點,我的頭頂...更多的Google濫用時間! (也許有人可能會向我扔東西?我的Google Fu不存在。) – Thromordyn 2011-03-10 16:31:58

+0

除非您確切知道該物品的名稱,否則我不會這樣做。否則,一個錯位的「會給你帶來嚴重的後果。 – Alfonso 2011-03-10 17:30:32

+0

@frenetisch:出色的點,總是消毒的字符串。在這裏忘記了。 – MPelletier 2011-03-10 17:40:38