我有一个像这样的sqlite3表“地址”:
+----+------+--------+
| ID | name | number |
+----+------+--------+
| 1 | John | 413434 |
+----+------+--------+
我想填充全局矢量,我可以在其他地方使用它并将其与其他一些数据连接起来。 到目前为止,我有这个:
...
#include <sqlite3.h>
using namespace std;
static int callbackDB(void *NotUsed, int argc, char **argv, char **szColName)
{
for(int i = 0; i < argc; i++)
cout << szColName[i] << " = " << argv[i] << endl;
return 0;
}
int main(int argc, char* argv[]) {
vector<vector<string> > table;
for( int i = 0; i < 2; i++ )
table.push_back(std::vector< std::string >());
sqlite3 *db;
char *szErrMsg = 0;
// open database
int rc = sqlite3_open("database.db", &db);
const char *query;
query = "SELECT * FROM addresses";
rc = sqlite3_exec(db, query, callbackDB, 0, &szErrMsg);
return 0;
}
我怎样才能以矢量或其他方式获得结果,以便我能够更轻松地使用它?
答案 0 :(得分:6)
sqlite3_exec
的第四个参数可用于将信息传递给回调。
在您的情况下,指向table
的指针将非常有用:
typedef vector<vector<string> > table_type;
static int callbackDB(void *ptr, int argc, char* argv[], char* cols[])
{
table_type* table = static_cast<table_type*>(ptr);
vector<string> row;
for (int i = 0; i < argc; i++)
row.push_back(argv[i] ? argv[i] : "(NULL)");
table->push_back(row);
return 0;
}
...
rc = sqlite3_exec(db, query, callbackDB, &table, &errmsg);
然而,使用这样的回调并不是很有用,因为你只得到一堆裸字符串。 您应该直接使用prepare / step / finalize接口,以便使用正确的数据类型:
class Address {
public:
Address(int id, const string& name, const string& number);
...
}
...
vector<Address> addresses;
sqlite3_stmt *stmt;
rc = sqlite3_prepare_v2(db, "SELECT id, name, number FROM addresses",
-1, &stmt, NULL);
if (rc != SQLITE_OK) {
cerr << "SELECT failed: " << sqlite3_errmsg(db) << endl;
return ...; // or throw
}
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
int id = sqlite3_column_int(stmt, 0);
const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
const char* number = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
// let's assume number can be NULL:
addresses.push_back(Address(id, name, number ? number : ""));
}
if (rc != SQLITE_DONE) {
cerr << "SELECT failed: " << sqlite3_errmsg(db) << endl;
// if you return/throw here, don't forget the finalize
}
sqlite3_finalize(stmt);