-1

在下面的代码中,一切似乎都是正确的,但是无论我提供什么数据,带注释的行总是返回 null 的错误代码。我已经研究并更改了我能想到的所有参数。第一个 sqlite3_bind_text 行成功,接下来的三个每次都失败。我想不通。帮助?

-(void)fillSqliteDb
{
    sqlite3 *database;
    if (sqlite3_open([[self sqliteFilePath] UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Failed to open database");
    }

    NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FUNCTIONS  (nouns TEXT, verbs TEXT, adverbs TEXT, adjectives TEXT);";
    char *errorMsg;
    if (sqlite3_exec (database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Error creating table: %s", errorMsg);
    }
    sqlite3_stmt *stmt;

    for (int i=0; i<260; i++) {
        NSString * pln = self.pluralNouns[i]; // pre-filled array of 260 words
        NSString * vrb = self.verb[i]; // pre-filled array of 260 words
        NSString * adv = self.adverb[i]; // pre-filled array of 260 words
        NSString * adj = self.adjective[i]; // pre-filled array of 260 words

        char *update = "INSERT INTO FUNCTIONS (nouns, verbs, adverbs, adjectives) VALUES (?, ?, ?, ?);";

        if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
            sqlite3_bind_text(stmt, 1, [pln UTF8String], -1, NULL);
            if (sqlite3_step(stmt) != SQLITE_DONE) // Works, word ends up in database
              NSLog(@"Error updating table: %s", errorMsg);
           sqlite3_bind_text(stmt, 2, [vrb UTF8String], -1, NULL);
            if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
                NSLog(@"Error updating table: %s", errorMsg);
            sqlite3_bind_text(stmt, 3, [adv UTF8String], -1, NULL);
            if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
                NSLog(@"Error updating table: %s", errorMsg);
            sqlite3_bind_text(stmt, 4,[adj UTF8String], -1, NULL);
            if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
                NSLog(@"Error updating table: %s", errorMsg);
        }

    }

}
4

1 回答 1

7

这段代码有几个问题。

  1. 只调用sqlite3_prepare_v2一次。for在循环之前执行它。
  2. 您需要sqlite3_bind_xxx为每个变量调用一次,全部在调用sqlite3_step.
  3. sqlite2_step每个循环只调用一次。在循环结束时执行此操作。
  4. 在循环结束调用后sqlite3_step,您需要调用sqlite3_reset.
  5. 在循环之后,您需要调用sqlite3_finalize准备好的语句。
  6. 由于您在方法开始时打开了数据库连接,因此您需要在方法结束时将其关闭。
  7. errorMsg在检查每个sqlite3_step调用的结果后,您对所有日志的使用是错误的。errorMsg仅从调用设置为sqlite3_exec. 要获取您需要使用的其他调用的错误消息sqlite3_errmsg

更新代码:

- (void)fillSqliteDb {
    sqlite3 *database;
    if (sqlite3_open([[self sqliteFilePath] UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Failed to open database");
    }

    NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FUNCTIONS  (nouns TEXT, verbs TEXT, adverbs TEXT, adjectives TEXT);";
    char *errorMsg;
    if (sqlite3_exec (database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Error creating table: %s", errorMsg);
    }

    sqlite3_stmt *stmt;
    char *update = "INSERT INTO FUNCTIONS (nouns, verbs, adverbs, adjectives) VALUES (?, ?, ?, ?);";

    if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
        for (int i=0; i<260; i++) {
            NSString * pln = self.pluralNouns[i]; // pre-filled array of 260 words
            NSString * vrb = self.verb[i]; // pre-filled array of 260 words
            NSString * adv = self.adverb[i]; // pre-filled array of 260 words
            NSString * adj = self.adjective[i]; // pre-filled array of 260 words

            sqlite3_bind_text(stmt, 1, [pln UTF8String], -1, NULL);
            sqlite3_bind_text(stmt, 2, [vrb UTF8String], -1, NULL);
            sqlite3_bind_text(stmt, 3, [adv UTF8String], -1, NULL);
            sqlite3_bind_text(stmt, 4, [adj UTF8String], -1, NULL);

            if (sqlite3_step(stmt) != SQLITE_DONE) // ALWAYS RETURNS Error: NULL
                NSLog(@"Error updating table: %s", sqlite3_errmsg(database));
            sqlite3_reset(stmt);
        }

        sqlite3_finalize(stmt);
    }

    sqlite3_close(database);
}
于 2013-06-02T21:57:13.587 回答