【问题标题】:SQlite query - How do I retrieve multiple column data?SQlite 查询 - 如何检索多列数据?
【发布时间】:2012-11-24 18:53:01
【问题描述】:

我很难在网上找到一个关于使用 xcode 和 cocos2dx 从 SQlite DB 获取多个值的工作示例。这是我的 sql 查询:

char sql_query[100];
sprintf(sql_query, "SELECT * FROM SQList WHERE ColumnD BETWEEN %d AND %d ORDER BY RANDOM() LIMIT 1", MinColumnD, MaxColumnD);

它本身的查询似乎可以工作,主要问题是如何将我从“select *”收集的值获取到另一个 int 或 char 参数中以便我可以使用它?

我发现一些例子提到了使用结构体的回调或提到使用 sqlite3_prepare_v2 和 step 方法。

不过,我无法找到这两种方法的示例,请帮忙!

【问题讨论】:

  • 有一个教程提到here

标签: c++ xcode sqlite


【解决方案1】:

当使用sqlite3_exec时,你必须从字符串中转换所有值,并且你必须使用回调的void *指针或者一些全局变量来返回数据:

struct MyData {
    string A;
    int B, C;
};

int exec_callback(void *ptr, int argc, char *argv[], char *names[])
{
    vector<MyData> *list = reinterpret_cast<vector<MyData> *>(ptr);
    MyData d;
    d.A = argv[0] ? argv[0] : "";
    d.B = atoi(argv[1]);
    d.C = atoi(argv[2]);
    list->push_back(d);
    return 0;
}

void query_with_exec()
{
    vector<MyData> list;

    char *errmsg = NULL;
    sqlite3_exec(db, "SELECT a, b, c FROM SQList /* WHERE ... */",
                 exec_callback, &list, &errmsg);
    if (errmsg) {
        printf("error: %s!\n", errmsg);
        return;
    }

    // use list ...
}

当使用sqlite3_prepare*时,你必须循环调用sqlite3_step,直到它不再返回SQLITE_ROW(当你期望只有一条记录时,你只能调用一次):

void query_with_step()
{
    vector<MyData> list;
    sqlite3_stmt *stmt;

    int rc = sqlite3_prepare_v2(db, "SELECT a, b, c FROM SQList /* WHERE ... */",
                                -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        printf("error: %s!\n", sqlite3_errmsg(db));
        return;
    }

    for (;;) {
        rc = sqlite3_step(stmt);
        if (rc == SQLITE_DONE)
            break;
        if (rc != SQLITE_ROW) {
            printf("error: %s!\n", sqlite3_errmsg(db));
            break;
        }

        MyData d;
        const char *text = (const char *)sqlite3_column_text(stmt, 0);
        d.A = text ? text : "";
        d.B = sqlite3_column_int(stmt, 1);
        d.C = sqlite3_column_int(stmt, 2);
        list.push_back(d);
    }

    sqlite3_finalize(stmt);

    // use list ...    
}

【讨论】:

  • 我认为这个方向更符合我的需要,因为我使用的是 C++ 中的 cocos2dx。我仍然面临问题......在 sqlite3_exec 方法中,我在回调的列表中得到一个 EXC_BAD_ACCESS->push_back(d);部分。当我使用 prepare_v2 方法时,我在 int rc = sqlite3_prepare_v2(db, "SELECT a, b, c FROM SQList /* WHERE..) 上得到一个 EXC_BAD_ACCESS 我假设这与我声明它的方式有关,但是有点卡在这里。
  • 为我工作。编写一个minimal程序,只打开数据库并调用sqlite3_prepare_v2;它也崩溃了吗?
  • 太棒了!感谢您的建议,我现在发现了问题!就像没有为 char sql_quer 分配足够的内存一样简单!
【解决方案2】:

使用“SELECT”查询获取值并将您的 char 和 int 值存储在一个数组中。创建一个 NSMUtableArray 并存储您将从 SELECT 查询中获取的值。以下代码将帮助您

-(int)find_putts_count:(int)holeno{
  sqlite3 *database;
 NSString *databasePath;
 NSMUtableArray *arr_tracking_details = [[NSMUtableArray alloc] init];
 int putts = -1;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:@"GolfElite.sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
    // Setup the SQL Statement and compile it for faster access
    NSString *sqlStatement = nil;
            sqlStatement = [NSString stringWithFormat:@"select Putts from Holes WHERE HoleNo == %d and ShotNo == %d and PlayerId == '%@'",holeno,1,[arr_players_id objectAtIndex:scorecard_player_no]];
    sqlite3_stmt *compiledStatement;
    if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) 
    {
        if(sqlite3_step(compiledStatement) == SQLITE_ROW)   
        {
            [arr_tracking_details addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)]];
             [arr_tracking_details addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement,6)]];
            [arr_tracking_details addObject:[NSString stringWithFormat:@"%d",(int)sqlite3_column_int(compiledStatement, 4)]];

            putts = (int)sqlite3_column_int(compiledStatement, 0);
        }
    }
    sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return putts;
}

【讨论】:

  • 这不是 C++
猜你喜欢
  • 1970-01-01
  • 2013-10-19
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多