【问题标题】:sqlite3_step always returns SQLITE_DONEsqlite3_step 总是返回 SQLITE_DONE
【发布时间】:2014-11-11 07:01:52
【问题描述】:

我正在尝试从单表 sqlite 数据库中检索数据,但 (sqlite3_step(statement) == SQLITE_ROW) 始终返回 false。我已经手动检查了数据库中的值并且它们存在。完整代码如下:

-(NSArray *)findByPartNumber:(NSString *)partNumber
{
    const char *dbpath = [databasePath UTF8String];
    NSMutableArray *resultArray = [[NSMutableArray alloc] init];
    if(sqlite3_open(dbpath, &database) == SQLITE_OK)
    {
        NSString *querySQL = [NSString stringWithFormat:@"SELECT Description, ListPrice FROM PriceList WHERE PartNumber=?"];
        const char *query_stmt = [querySQL UTF8String];
        if(sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
        {
            sqlite3_bind_text(statement, 1, [partNumber UTF8String], -1, SQLITE_STATIC);
            if(sqlite3_step(statement) == SQLITE_ROW)
            {
                NSString *description;
                NSString *listPrice;

                const char *tmp1 = (const char *)sqlite3_column_text(statement, 0);
                const char *tmp2 = (const char *)sqlite3_column_text(statement, 1);

                if(tmp1 == NULL)
                    description = nil;
                else
                {
                    description = [[NSString alloc] initWithUTF8String:tmp1];
                    [resultArray addObject:description];
                }
                if(tmp2 == NULL)
                    listPrice = nil;
                else
                {
                    listPrice = [[NSString alloc] initWithUTF8String:tmp2];
                    [resultArray addObject:listPrice];
                }
                sqlite3_finalize(statement);
            }
        }
        sqlite3_close(database);
    }

    if([resultArray count] == 0)
        return nil;
    else
        return resultArray;
}

代码进入 sqlite3_prepare_v2 块,但跳过 sqlite3_step 块。我错过了什么吗?

【问题讨论】:

    标签: ios xcode sqlite


    【解决方案1】:

    您的实施存在问题。

    你写过这样的:

    sqlite3_bind_text(statement, 1, [partNumber UTF8String], -1, SQLITE_STATIC);
    if(sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
       ...
    }
    

    您只能将值绑定到准备好的语句,因此将上面的代码更改为:

    if(sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
       sqlite3_bind_text(statement, 1, [partNumber UTF8String], -1, SQLITE_STATIC);
       ...
    }
    

    【讨论】:

    • 感谢您的回复,我已经按照您所说的移动了这条线,但仍然得到相同的结果。还有什么我想念的吗?
    • @mbeem:你确定查询是正确的。无论是否有效,只需手动执行即可。
    • 还有其他想法吗?环顾四周,我看到了代码正确但需要重建数据库的类似问题。我不相信这会解决我的问题,因为我可以手动查询它,而且有 1500 行,所以我不想再做一次......
    • @mbeem 我认为 bind_text 会导致问题。取而代之的是,暂时编写一个硬编码查询并检查它是否正常工作(然后不需要 bind_text),如果工作正常,问题在于 bind_text 调用
    • @mbeem 你能分享一个与你的数据库具有相同结构的示例数据库,其中包含一些虚拟值吗?
    【解决方案2】:

    原来 sqlite3_step 总是返回 SQLITE_DONE 因为没有数据。我的 databasePath 设置不正确。

    不正确的代码:

    NSString *docsDir;
    NSArray *dirPaths;
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = dirPaths[0];
    databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: @"databaseName.sqlite"]];
    

    正确代码:

    databasePath = [[NSBundle mainBundle] pathForResource:@"databaseName" ofType:@"sqlite"];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-05-29
      相关资源
      最近更新 更多