【问题标题】:sqlite3 int problemsqlite3 int问题
【发布时间】:2011-07-12 19:57:34
【问题描述】:

我已经完全放弃了,所以如果版主碰巧过来,删除会很好。
不提这个问题并没有什么坏处,但 CoreData 要好得多,你知道吗?


我有一个用于处理表内容的 sqlite 数据库。一切都很棒(比我看过的其他选项要容易得多),但是我在使用整数时遇到了麻烦。启动应用程序后我第一次去编辑项目时,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
}

【问题讨论】:

  • 可能需要一些代码来解决这个问题,以及一个表定义。问题可能不在 SQLite 本身。
  • 我想通了,但我不知道该放什么。粘贴所有内容似乎有点傻,但也许我应该......
  • 从表定义和更新例程开始。
  • 我认为您的更新和插入例程可能都需要。
  • 您是否考虑到绑定到列使用基于 1 的索引,而从列中读取使用基于 0 的索引? (可能反过来,我不确定了)

标签: iphone objective-c xcode sqlite


【解决方案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));
    }
}

【讨论】:

  • 我真的不知道该怎么做……是时候再滥用 Google 了! (也许有人会向我扔东西?我的 Google Fu 不存在。)
  • 除非您确切知道该项目名称中的内容,否则我不会这样做。否则放错地方的 ' 会让你大吃一惊。
  • @frenetisch:很好,总是清理字符串。在这里忘记了。
  • 这看起来确实有点干净,但有 2 个错误和 1 个警告。 (baseString 未声明;函数“sqlite3_exec”的参数太少;从不兼容的指针类型传递“sqlite3_exec”的参数 1(我假设这个警告是第一个错误的结果))//我能得到一本好的 sqlite3 书吗?不全是错误(iPhone 0.99 的 Cocos2d (Pablo Ruiz))或过时(iPhone SDK Development (Dudney Adamson))的东西肯定会更好。
  • 对不起@Thromordyn,我用于sqlite3_exec 的语法全错了。要修好了与此同时,documentation。 sqlite 网站上有很多内容,都是最新的。
猜你喜欢
  • 1970-01-01
  • 2011-09-26
  • 2011-10-08
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 2010-12-19
  • 1970-01-01
相关资源
最近更新 更多