当前位置:   article > 正文

深入理解SQLite3之sqlite3_exec及回调函数_vs2015中使用sqlite3数据库求某列的最大值,使用回调函数

vs2015中使用sqlite3数据库求某列的最大值,使用回调函数

    sqlite3的C/C++接口API主要有3个重要函数,分别为

  1. 1、sqlite3_open(const char* filename, sqlite3 **ppDb);
  2. 2int sqlite3_exec(
  3. sqlite3*, /* An open database */
  4. const char *sql, /* SQL to be evaluated */
  5. int (*callback)(void*,int,char**,char**), /* Callback function */
  6. void *, /* 1st argument to callback */
  7. char **errmsg /* Error msg written here */
  8. );
  9. 3、sqlite3_close(sqlite3*)

    sqlite3_open和sqlite3_close是很好理解的,分别是打开和关闭对应的数据库。而sqlite3_exec函数是sqlite3的API函数,可以实现各种功能,所以理解sqlite3_exec对于实际的 编程十分有必要,我们来详细分析sqlite3_exec函数,

1、sqlite3_exec函数 形参

  1. sqlite3*            : open 打开的数据库
  2. const char* sql,    : 执行的sql功能语句
  3. *callback,    : sql语句对应的回调函数
  4. void* data,         : 传递给回调函数的 指针参数
  5. char **errmsq       : 错误信息

   其中 const char* sql表示 相应的 sql语句,如果我们直接在linux下,使用shell是可以实现所有的sqlite功能的,但是如果进行C或C++ 开发程序时,很明显是没有shell可用的,所以这个 *sql就是对应sqlite功能命令的 “字符串”,后面我们举例来分析。回调函数指针callback则是 *sql功能命令对应的 回调函数,所谓 回调函数的意思是,会先执行*sql对应的功能命令,然后将结果传递给回调函数,回调函数根据结果再进一步执行。这代表着,这个 “回调函数”才是最有意义的,我们要讲我们需要的功能,通过回调函数来实现,不管是获取数据库表中有效信息,还是其他动作。

2、sqlite3_exec的回调函数 callback

   我们还是来先看下回调函数的参数:

  1. typedef int(*sqlite_callback)(void* para, int columenCount, char** columnValue, char** columnName);
  2. 参数:
  3. para : 由sqlite3_exec传入的参数指针,或者说是指针参数
columnCount:	查询到的这一条记录由多少个字段(多少列)
  1. columnValue : 该参数是双指针,查询出来的数据都保存在这里,它是一个1维数组,每一个元素都是一
  2. char*,是一个字段内容,所以这个参数就可以不是单字节,而是可以为字符串等不定
  3. 长度的数值,用字符串表示,以'\0'结尾。
  1. columnName : 该参数是双指针,语columnValue是对应的,表示这个字段的字段名称,
  2. 返回 : 执行成果则返回SQLITE_OK,否则返回其他值

   这里面有几个地方容易理解错,回调函数的参数一定是 sql功能命令执行结果的进一步处理,其中para好理解,就是sqlite3_exec传递的参数,

   columnCount:表示sql功能结果的“字段”,也就是“列”的个数,没错,就是“列”的个数。

   另外需要特别注意的是:回调函数多数时候不是执行1次,而是会循环执行n次,当我们使用select进行sql功能时,往往输出的结果会是 多行,那么 有n行,就会执行n次的 回调函数。举例如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sqlite3.h>
  4. static int callback(void *data, int argc, char **argv, char **azColName){
  5. int i;
  6. fprintf(stderr, "%s: ", (const char*)data);
  7. for(i=0; i<argc; i++){
  8. printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  9. }
  10. printf("\n");
  11. return 0;
  12. }
  13. int main(int argc, char* argv[])
  14. {
  15. sqlite3 *db;
  16. char *zErrMsg = 0;
  17. int rc;
  18. char *sql;
  19. const char* data = "Callback function called";
  20. /* Open database */
  21. rc = sqlite3_open("test.db", &db);
  22. if( rc ){
  23. fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  24. exit(0);
  25. }else{
  26. fprintf(stderr, "Opened database successfully\n");
  27. }
  28. /* Create SQL statement */
  29. sql = "SELECT * from COMPANY";
  30. /* Execute SQL statement */
  31. rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
  32. if( rc != SQLITE_OK ){
  33. fprintf(stderr, "SQL error: %s\n", zErrMsg);
  34. sqlite3_free(zErrMsg);
  35. }else{
  36. fprintf(stdout, "Operation done successfully\n");
  37. }
  38. sqlite3_close(db);
  39. return 0;
  40. }

  这个数据库中表的内容如下(这里照搬了https://www.runoob.com/sqlite/sqlite-c-cpp.html 中的例子):

  1. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
  2. "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
  3. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
  4. "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \
  5. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
  6. "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
  7. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
  8. "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

所以执行的结果:

  1. Opened database successfully
  2. Callback function called: ID = 1
  3. NAME = Paul
  4. AGE = 32
  5. ADDRESS = California
  6. SALARY = 20000.0
  7. Callback function called: ID = 2
  8. NAME = Allen
  9. AGE = 25
  10. ADDRESS = Texas
  11. SALARY = 15000.0
  12. Callback function called: ID = 3
  13. NAME = Teddy
  14. AGE = 23
  15. ADDRESS = Norway
  16. SALARY = 20000.0
  17. Callback function called: ID = 4
  18. NAME = Mark
  19. AGE = 25
  20. ADDRESS = Rich-Mond
  21. SALARY = 65000.0
  22. Operation done successfully

   可以看出来,由于sql命令行为 select* from COMPANY,该命令会将表中所有信息都输出,总共5个字段(列),包含4条信息(行),所以这个回调函数会被执行4次,理解这个逻辑,非常重要。

  而且回调函数的后两个参数是 双指针 ,也就是 指针的指针,包含了2层的指向,里层的 指向是 对应具体的数据指针,外层的指向则是  数据指针序号,也可以理解成 “列”索引。我们通过这两个指针能够进一步 编写 自定义功能代码。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/173296
推荐阅读
相关标签
  

闽ICP备14008679号