C. sqlite3_exec中的SQLite:回调函数中的参数设置在main()中调用时打印不完整的数据

我正在努力实现一些非常基本的东西。 但不幸的是,我无法得到预期的结果。

我有一个名为emp_info的sqlite表,在以下字段中有9个员工记录:

SR_NO [0],NAME [1],AGE [2],SEX [3],ADDRESS [4],EMPID [5],CARDID [6]和SALARY [7]

要访问该表并按照sql查询获取员工记录,我在C中有以下程序:

#include  #include  #include  #include  static int callback(void *param, int argc, char *argv[], char **azColName){ int i=0; if(argc == 0) return 0; char **res = (char **)param; *res = (char *)realloc(*res, sizeof(*res)); //for(i=0; i<argc; i++){ //printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); strcpy(*res, argv[1], sizeof(*res)); printf("%s\n", *res); // } return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; char *param; rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db); if( rc ) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); } else { fprintf(stderr, "\nOpened database successfully\n\n"); } sql="select * from emp_info;" rc = sqlite3_exec(db, sql, callback, &param, &zErrMsg); if( rc != SQLITE_OK ) { fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } else { fprintf(stdout, "Operation done successfully\n\n"); printf("the value of data is %s \n\n", param); } free(param); sqlite3_close(db); return 0; } 

输出如下:`成功打开数据库

 AAA BBB CCC DDD EEE FFF GGG HHH III Operation done successfully the value of data is III 

我预计所有的AAA,BBB,CCC,……都将存储在param中并将被打印出来。 但那并没有发生。 param仅采用最后一条记录。

为什么会这样? 我怀疑strcpy()正在创建问题。

请帮助。

除此之外,我的真正目的是让所有有效的员工记录(根据sql查询)存储在param中 ,它应该显示所有字段(SR_NO [0],NAME [1],AGE [2],SEX [3],ADDRESS [4],EMPID [5],CARDID [6]和SALARY [7])。 例如,如果我向sql提供以下查询

 sql="SELECT * FROM emp_info WHERE AGE>40"; 

那么param应该显示如下结果

 7 GGG 41 MALE G1G2G3G4 307 7777GGG 77777 8 HHH 42 FEMALE H1H2H3H4 308 8888HHH 88888 9 III 43 FEMALE I1I2I3I4 309 9999IIII 99999 

而不只是一个专栏。我怎么能实现这一目标?

先感谢您。

致力于CL提出的建议。 我开始致力于在基于游标的API上编写代码。 我得到了所需的输出。

 #include  #include  #include  #include  #include  #include  using namespace std; class sqliteDB { private: int rc; sqlite3 *db; char *zErrMsg; const char *sql; sqlite3_stmt * stmt; list answer; public: //================================XX=====================================// bool connectDB() { rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db); if( rc ) { cerr << "Can't open database: " << sqlite3_errmsg(db) << endl; sqlite3_close(db); exit(1); } else { std::cout<<"\n\nDatabase opened successfully\n\n"; } } //===============================XX=====================================// void allEmp() { int AGE; //Preparing the statement rc=sqlite3_prepare(db,"SELECT * FROM emp_info WHERE AGE>40;", -1, &stmt, NULL ); if (rc != SQLITE_OK){ throw string(sqlite3_errmsg(db)); } else{ cout<<"\n\nThe statement was prepared successfully\n\n"; } // Creating List Container // cout << "\n\nList answer was created successfully\n\n"; while(sqlite3_step(stmt) == SQLITE_ROW) { cout << "Rows" << endl; int column = sqlite3_column_count(stmt); for(int i = 0; i < column; i++) { cout << "Columns" << endl; answer.push_back(string((const char *) sqlite3_column_text(stmt, i))); } } sqlite3_finalize(stmt); cout << "\n\nDatabase was closed successfully\n\n"; } //==============================XX=====================================// void printList(){ int s = answer.size(); for( list::const_iterator it = answer.begin(); it != answer.end(); it++) cout << it->c_str() << endl; } //===================================XX===============================// }; int main() { sqliteDB object1; object1.connectDB(); object1.allEmp(); object1.printList(); cout << "\n\nAll the statement were executed properly\n\n"; return 0; } //========================END OF CODE===========================// 

输出如下

  Database opened successfully The statement was prepared successfully List answer was created successfully Rows Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Rows Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Rows Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Columns Database was closed successfully 7 GGG 41 MALE G1G2G3G4 307 7777GGG 77777 9833446677 abi@gmail.com 07:08:1947 NONE 8 HHH 42 FEMALE H1H2H3H4 308 8888HHH 88888 9833446688 abj@gmail.com 08:09:1947 NONE 9 III 43 FEMALE I1I2I3I4 309 9999IIII 99999 9833446699 abk@gmail.com 09:10:1947 NONE All the statement were executed properly 

我遇到的主要问题是“<<”运算符的重载。

谢谢CL。

我不是这方面的专家,但是一个简单的谷歌搜索显示, sqlite3_exec()的语法是

 int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); 

注意第4个参数,它被假定为void *

根据您对变量和调用约定的定义,

 char *param; 

 rc = sqlite3_exec(db, sql, callback, &param, &zErrMsg); 

你得到的第四个参数错了。 您可能希望将其重写为

 rc = sqlite3_exec(db, sql, callback, (void *)param, &zErrMsg); 

注意:[如果sqlite3_exec()已经没有注意了]您可能需要在传递给sqlite3_exec()之前将内存分配给param 。 此外,您可能希望对其进行一些完整性和有效性检查,而不是直接将argv传递给回调。

您从答案中获取了代码,目标是读取单个结果行。 strcpy覆盖同一变量的先前值。

您应该使用基于游标的API ,并在循环中调用sqlite3_step

 ... while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { my_object *o = new ...; o->set_field(sqlite3_column_xxx(stmt, 1); ... my_list.add(o); } ...