• 《SQLite3 — C语言接口API》


      编译C的时候需要添加-lsqlite3

    1.sqlite3_open和sqlite3_close

    #include <sqlite3.h>
    sqlite3_open(const char* filename, sqlite3 **ppDb);
    作用:打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。
    参数:
      filename:要打开的数据库。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
      ppDb:返回的SQLite的数据库连接对象
    
    sqlite3_close(sqlite3*)
    该函数关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
    
    如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。

    实例:

    #include <stdio.h>
    #include <sqlite3.h>
    
    int main(int argc, char* argv[])
    {
       sqlite3 *db;
       char *zErrMsg = 0;
       int rc;
    
       rc = sqlite3_open("test.db", &db);
    
       if( rc ){
          fprintf(stderr, "Can't open database: %s
    ", sqlite3_errmsg(db));
          exit(0);
       }else{
          fprintf(stderr, "Opened database successfully
    ");
       }
       sqlite3_close(db);
    }
    

      

    2.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 */
        );
    参数:
        sqlite3*            : open 打开的数据库
        const char* sql,    : 执行的sql功能语句
        *callback,          : sql语句对应的回调函数
        void* data,         : 传递给回调函数的 指针参数
        char **errmsq       : 错误信息
    

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

      

    3.sqlite3_exec的回调函数 callback

    typedef int(*sqlite_callback)(void* para, int columenCount, char** columnValue, char** columnName);
    
    参数:
      para:由sqlite3_exec传入的参数指针
      columnCount:查询到的这一条记录有多少个字段(多少列)
      columnValue:该参数是个双指针,查询出来的数据都保存在这里,它是一个一维数据,每一个元素都是一个char*,是一个字段内容
      columnName:该参数是双指针,与columnValue是对应的,表示这个字段的字段名称。
    返回:
      执行成功则返回SQLITE_OK,否则返回其他值

       注意:回调函数的参数一定是 sql功能命令执行结果的进一步处理

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

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

    #include <stdio.h>
    #include <stdlib.h>
    #include <sqlite3.h>
     
    static int callback(void *data, int argc, char **argv, char **azColName){
       int i;
       fprintf(stderr, "%s: ", (const char*)data);
       for(i=0; i<argc; i++){
          printf("%s = %s
    ", azColName[i], argv[i] ? argv[i] : "NULL");
       }
       printf("
    ");
       return 0;
    }
     
    int main(int argc, char* argv[])
    {
       sqlite3 *db;
       char *zErrMsg = 0;
       int rc;
       char *sql;
       const char* data = "Callback function called";
     
       /* Open database */
       rc = sqlite3_open("test.db", &db);
       if( rc ){
          fprintf(stderr, "Can't open database: %s
    ", sqlite3_errmsg(db));
          exit(0);
       }else{
          fprintf(stderr, "Opened database successfully
    ");
       }
     
       /* Create SQL statement */
       sql = "SELECT * from COMPANY";
     
       /* Execute SQL statement */
       rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
       if( rc != SQLITE_OK ){
          fprintf(stderr, "SQL error: %s
    ", zErrMsg);
          sqlite3_free(zErrMsg);
       }else{
          fprintf(stdout, "Operation done successfully
    ");
       }
       sqlite3_close(db);
       return 0;
    }
    

      数据库中的表如下:

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

      执行结果:

    Opened database successfully
    Callback function called: ID = 1
    NAME = Paul
    AGE = 32
    ADDRESS = California
    SALARY = 20000.0
     
    Callback function called: ID = 2
    NAME = Allen
    AGE = 25
    ADDRESS = Texas
    SALARY = 15000.0
     
    Callback function called: ID = 3
    NAME = Teddy
    AGE = 23
    ADDRESS = Norway
    SALARY = 20000.0
     
    Callback function called: ID = 4
    NAME = Mark
    AGE = 25
    ADDRESS = Rich-Mond
    SALARY = 65000.0
     
    Operation done successfully
    

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

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

  • 相关阅读:
    CPU、io、mem之间的关系
    SSH交互式脚本StrictHostKeyChecking选项 benchmode=yes
    Linux学习笔记:fuser和lsof
    /proc/sys/kernel/sysrq /proc/sysrq-trigger----强制重启/触发器
    Android UI学习
    Android之TabHost布局(转)
    android AsyncTask介绍(转)
    android:imeOptions属性(转)
    Android:dimen尺寸资源文件的使用(转)
    解决Android解析图片的OOM问题!!!(转)
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/13224472.html
Copyright © 2020-2023  润新知