Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQlite query - How do I retrieve multiple column data?

Tags:

c++

sqlite

xcode

I'm having great difficulty to find a working example on the net regarding getting multiple values from a SQlite DB using xcode and cocos2dx. Here is the sql query I have:

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

The query it self seems to work, the main problem is how do I get the values that I collect from 'select *' into another int or char parameter so that I can use it?

Some example I found referred to using a callback to a struct or mentioned about using sqlite3_prepare_v2 and the step method.

I'm unable to find an example for either methods though, please help!

like image 247
user1842318 Avatar asked Feb 19 '23 09:02

user1842318


1 Answers

When using sqlite3_exec, you have to convert all values from strings, and you have to use the callback's void * pointer or some global variable to return data:

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 ...
}

When using sqlite3_prepare*, you have to call sqlite3_step in a loop until it does not return SQLITE_ROW anymore (when you expect only one record, you can call it only once):

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 ...    
}
like image 57
CL. Avatar answered Feb 20 '23 21:02

CL.