【问题标题】:Need help storing a value I get from a sqlite3 DB in a C++ variable需要帮助将我从 sqlite3 DB 获得的值存储在 C++ 变量中
【发布时间】:2021-10-11 05:21:04
【问题描述】:

我有一个“Data.db”,其中包含 3 个表,用于存储某种“足球数据”。 一张桌子供“团队”使用,另一张桌子供“玩家”使用。我现在要做的是从“团队”中获取“最高”ID,以便将新生成的玩家分配给该团队。 (每个玩家都有一个_teamId)

我可以通过使用这个查询和一个只打印我需要的值的 callback_id 来打印我想要的 ID。

查询:

string query = "SELECT COUNT(ID) FROM TEAMS;";

highest_id = (sqlite3_exec(db, query.c_str(), callback_id, 0, &messageError));

回调:

int Team::callback_id(void* data, int count, char** values, char** columns) {
    int id = atoi(values[1]);

    std::cout << "callback_id says: " << id << endl;

    return 0;
}

我必须做些什么才能将回调函数中的这个 id 存储在一个变量中,以便以后在我的程序中使用?似乎我不能只返回它,也不能只将 id 值分配给我的Team::_id,因为它给了我一个错误: 'invalid use of member ‘Team::_id’ in static member function'

我们将不胜感激。我仍在尝试了解有关 sqlite3 和回调函数的更多信息,但我在这个问题上浪费了太多时间,以至于我不知道我还能尝试什么。

【问题讨论】:

  • C 库中经常使用 void* 指针为函数操作提供上下文。您可以将其视为this 指针的扩展版本。您应该能够将您的 c++ 对象放在那里并存储它。

标签: c++ sqlite


【解决方案1】:

您在sqlite3_exec 中有一个void* 参数,您当前将其设置为0。相反,将指针传递给那里的对象。这样就可以在回调的对象中存储您喜欢的内容。

通常会传递一个指向对象的指针并调用该对象中的非static 成员函数来处理回调。

例子:

class Team {
public:
    void func() {
        std::string query = "SELECT COUNT(ID) FROM TEAMS;";
        sqlite3_exec(db, query.c_str(), &Team::callback_id_proxy, this, &messageError);
        //                                                        ^^^^
    }

    // a static callback proxy, casting `data` to a `Team*`
    static int callback_id_proxy(void* data, int count, char** values, char** columns) {
        return static_cast<Team*>(data)->callback_id(count, values, columns);
    }

    int callback_id(int count, char** values, char** columns) {
        // here you can store what you like in your `Team` object
        if(count > 0) highest_id = atoi(values[0]);
        else highest_id = 0;
        return 0;
    }

    int highest_id;
};

注意:您可能想改用SELECT MAX(ID) FROM TEAMS;。否则,如果您删除一个团队然后添加一个新团队,您可能会得到重复。

另一种选择是制作funchighest_id static。我在这里将highest_id 重命名为number_of_teams,因为它就是这样。

class Team {
public:
    static int get_number_of_teams() {
        std::string query = "SELECT COUNT(ID) FROM TEAMS;";
        if(sqlite3_exec(db, query.c_str(),
                        &Team::callback_count,
                        nullptr,    // static function, no "this" available
                        &messageError) == SQLITE_ABORT)
            throw std::runtime_error("callback_id returned non-zero");

        return number_of_teams;
    }

    static int callback_count(void* data, int count, char** values, char** columns) {
        if(count > 0) {
            number_of_teams = atoi(values[0]);
            return 0;
        }
        return 1; // indicate error
    }

private:
    inline static int number_of_teams = -1;
};

【讨论】:

  • 非常感谢您的时间和帮助。我按照您建议的方式尝试了它,但不知何故,我总是以某种方式得到相同的 7 值。我不知道它来自哪里,但无论有多少团队存储在我的“团队”表中,它都不会改变。您知道是什么原因造成的吗?
  • 我还在我的 callback_id 中放了一个std::cout &lt;&lt; "ID in callback_id: " &lt;&lt; atoi(values[0]) &lt;&lt; std::endl; 来查找我的msitake,但它从不向控制台打印任何内容。我是否调用了错误的函数(我是否必须在您的 callback_id_proxy 中添加任何内容?)我显然对 C++ 很陌生,并且不熟悉 static_cast 或 '->'
  • @Embrano 不,callback_id_proxy 在我的回答中应该是完整的。如果您在callback_id 中打印它,count 会说什么?如果一切正常,它应该只有1。另外,打印没有转换的值:for(int i = 0; i &lt; count; ++i) std::cout &lt;&lt; '&gt;' &lt;&lt; values[i] &lt;&lt; "&lt;\n"; 看看是否显示任何内容
  • 另外:你已经把func() 变成了Team 的成员函数,对吧?
  • omg...我现在觉得很愚蠢.. count 没有说任何话,就像我的“回调 ID 中的 ID:”没有说任何话一样。我用我制作的这个 sh** 的一些早期草稿交叉检查了所有内容,并意识到在任何地方都没有'sqlite3_open(“Data.db”,&db)'。我在 func() 中添加了它,瞧,你给我的一切都像一个魅力。它给了我正确的 ID,我生成的新玩家也有正确的 team_id。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 2022-11-24
相关资源
最近更新 更多