C/C++调用sqlite3接口详解

qlite3的C/C++接口用法可分为两种:回调形式与非回调形式。所谓回调形式其实就是通过回调的方式处理sql语句执行结果,非回调形式就是待sql语句执行完毕后再通过返回值和相关函数来判断、获取执行结果。

一、sqlite3非回调形式接口用法

1、sqlite3_open   打开sqlite3数据库的连接

在sqlite3数据库管理系统中,用结构体sqlite3来表示一个打开的数据库对象(sqlite3数据库连接对象),函数原型及用法如下:
 

int sqlite3_open(const char *filename, sqlite3 **ppDb);
filename:要打开的sqlite3数据库的路径名
ppDb: 二级指针,用来保存打开的数据库的连接对象。
返回值: 成功返回SQLITE_OK,失败返回其他值。

2、 sqlite3_close: 关闭数据库连接对象

int sqlite3_close(sqlite3*);

3、SQL语句对象
    sqlite3_stmt 这个结构体用来描述一个SQL语句对象。我们的应用都是通过SQL语句对象去发送sql指令给数据库管理系统的。 

4、sqlite3_prepare_v2:  编译SQL语句,并创建一个SQL语句对象

 int sqlite3_prepare_v2(
      sqlite3 *db,           // 数据库连接对象
      const char *zSql,      // 指向原始sql语句(要编译的sql语句),可以包含变量名的
      int nByte,             // < 0: 编译zSql到第一个\0为止
                             // >0:  编译zSql中前面nByte个字符
                             // =0:  什么也不编译
      sqlite3_stmt **ppStmt, // *ppStmt用来保存编译好的sql语句对象
      const char **pzTail    // *pzTail如果不为空,则*pzTail指向zSql中编译的第一条完整sql语句后面的第一个字符。                 
    );
    返回值:成功返回SQLITE_OK,失败返回其他值.

zSql指向原始的SQL语句:
(1) 不包括参数名
     "CREATE TABLE SCORE (\
        NUM INTEGER PRIMARY KEY, \
        NAME VARCHAR(255) NOT NULL,\
        SCORE INTEGER\
        );"

        char *sql = "INSERT INTO STU VALUES(2, 'HULONGTENG', 53) ;";
(2)包括参数名

        parameters:

        编译的SQL语句中可以包含"变量/参数",其值可以在运行期间通过特定的参数接口来指定。
        char *sql = "INSERT INTO STU VALUES(变量, 变量, 变量) ;";

有如下几种方式指定变量名:

            :AAAA  命名参数,参数名为AAAA
            @AAAA 命名参数,参数名为@AAAA
            $AAAA 命令参数,参数名为$AAAA, 参数名可以包含一个或多个:: 和().

例子:
            char *sql = "INSERT INTO STU VALUES(@NUM, @NAME, @SCORE) ;";

4、给参数赋值
    (1)    获取参数索引。因为所有的绑定参数的函数,都是通过参数索引去指定参数的。
     sqlite3_bind_parameter_index用来获取zName在SQL语句对象sqlite3_stmt中的索引。

函数原型:     
 

int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
返回值:成功返回索引值(>0),假如没有匹配的参数名找到,则返回0

2) 给参数赋值: 绑定值到变量/参数

参数:  SQL语句对象,参数索引,要设置的参数值

int sqlite3_bind_double(sqlite3_stmt*, int , double);
int sqlite3_bind_int(sqlite3_stmt *, int , int);
int sqlite3_bind_int64(sqlite3_stmt *, int ,  sqlite3_int64);

参数: SQL语句对象,参数索引
        int sqlite3_bind_null(sqlite3_stmt* , int);

参数: SQL语句对象,参数索引,要设置的字符串指针,字符串的长度,函数指针用来释放字符串(可以为空)
        int sqlite3_bind_text(sqlite3_stmt *, int,  const char *,  int , void (*) (void *));

5、sqlite3_step: 用来执行编译好的SQL语句对象(由sqlite3_stmt指定),每次返回一行执行结果。

函数原型及用法:
 

int sqlite3_step(sqlite3_stmt*);
sqlite3_stmt:指向编译好的要执行的SQL语句对象
返回值: SQLITE_BUSY: 没获取到锁,语句没执行。
        SQLITE_DONE: sql语句执行完成。
        SQLITE_ERROR: 出错啦
        SQLITE_MISUSE: 使用方法不当
        SQLITE_ROW:  假如SQL语句执行有返回结果,SQLITE_ROW返回。然后调用者调用sqlite3_column解析结果。        

6、查询结果分析函数
若sql语句为SELECT语句,它的返回结果是一个结果表,则需要用额外的函数接口去获取这些结果表中的记录。

若调用sqlite3_step函数则需要判断返回值,并对执行结果表一行一行的处理,直到返回值为SQLITE_DONE为止。

int sqlite3_column_count(sqlite3_stmt *pStmt);   //返回结果行中有多少列        
int sqlite3_column_type(sqlite3_stmt *pStmt, int iCol);  //返回结果行中第iCol列的数据类型
返回值: SQLITE_INTEGER :整数类型
        SQLITE_FLOAT: 浮点类型
        SQLITE_TEXT: 文本类型,char *
        SQLITE_BLOB: blob
        SQLITE_NULL: 空类型

判断出类型后,调用如下相应类型的接口获取结果集中当前行中第iCol列的值。

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);
const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);
const char *sqlite3_column_name(sqlite3_stmt*, int iCol);
const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

也可以不通过sqlite3_step 函数来获取执行结果,使用sqlite3_get_table 函数直接获取整个结果表。

函数原型为:

int sqlite3_get_table(
  sqlite3 *db,          /* An open database */
  const char *zSql,     /* SQL to be evaluated */
  char ***pazResult,    /* Results of the query */
  int *pnRow,           /* Number of result rows written here */
  int *pnColumn,        /* Number of result columns written here */
  char **pzErrmsg       /* Error msg written here */
);
第1个参数为数据库连接对象。
第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾的char*字符串。
第3个参数是查询结果(可理解为二维数组的地址)。
第4个参数是查询出多少条记录(即查出多少行,不包括字段名那行)。
第5个参数是多少个字段(多少列)。
第6个参数是错误信息
pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn),因为前(*pnColumn)个是字段名

使用sqlite3_get_table 函数后,需要使用对应的sqlite3_free_table函数来释放查询结果所申请的内存。函数原型:

void sqlite3_free_table(char **result); //释放掉查询结果申请的内存空间

6、sqlite3_reset:用来复位sql语句对象,以便下一轮的参数赋值

int sqlite3_reset(sqlite3_stmt *pStmt);

7、sqlite3_finalize:用来销毁一个SQL语句对象,与sqlite3_prepare_v2创建的SQL语句对象对应。

int sqlite3_finalize(sqlite3_stmt *pStmt);

使用示例一(sqlite3_step 方式获取执行结果):

 

   #include <sqlite3.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
     
    int main(int argc, char *argv[])
    {
        sqlite3 *pdb;
        int r ;
        /*step 1: 打开数据库连接对象*/
        r = sqlite3_open(argv[1], &pdb );
        if (r != SQLITE_OK)
        {
            perror("sqlite3_open error");
            return -1;
        }
        /*step 2: sql语句对象。*/
        sqlite3_stmt *pStmt;
        char *sql=    "SELECT STUINFO.SID,SNAME,CNAME,SCORE\
                        FROM STUINFO, COURCE, SCORE\
                        WHERE STUINFO.SID = SCORE.SID \
                        AND COURCE.CID = SCORE.CID ;";            
        r = sqlite3_prepare_v2(
                    pdb, //数据库连接对象
                    sql, //指向原始sql语句字符串
                    strlen(sql) , //
                    &pStmt,
                    NULL
                );
        if (r != SQLITE_OK)
        {
            perror("sqlite3_prepare_v2 error:");
            return -1;
        }
        while (1)
        {
            static int first = 1;
            int i;
            /*2.2 执行SQL语句*/
            r = sqlite3_step(pStmt);
            if (r == SQLITE_DONE)
            {
                printf("o la\n");
                break;//执行完成
            }
            else if (r == SQLITE_ROW) //获取到一行的结果
            {
                int cNum =0 ;//结果集中有多少列
                cNum = sqlite3_column_count(pStmt);
                if (first)
                {
                    for (i = 0; i < cNum; i++)
                    {    
                        //返回结果集中第i列的名字
                        const char *p = sqlite3_column_name(pStmt, i);
                        printf("%s\t", p);
                    }
                    printf("\n---------------------------\n");
                    first = 0;
                }
                int iType; //第i列的数据类型
                for (i = 0; i < cNum; i++)
                {
                    //获取结果集中第i列的数据类型
                    iType = sqlite3_column_type(pStmt, i);
                    if (iType == SQLITE_INTEGER)
                    {
                        int iValue;
                        //获取结果集中第i列的数据值
                        iValue = sqlite3_column_int(pStmt, i);
                        printf("%d\t", iValue);
                    }else if (iType == SQLITE_FLOAT)
                    {
                        double iValue;
                        //获取结果集中第i列的数据值
                        iValue = sqlite3_column_double(pStmt, i);
                        printf("%g\t", iValue);
     
                        
                    }else if (iType == SQLITE_TEXT)
                    {
                        const char * iValue;
                        //获取结果集中第i列的数据值
                        iValue = sqlite3_column_text(pStmt, i);
                        printf("%s\t", iValue);
                    }
                }
                printf("\n");
            }
        }
        //销毁一个SQL语句对象
        sqlite3_finalize(pStmt);
        
        /*step 3: 关闭数据库连接对象*/
        sqlite3_close(pdb);
        return 0;
    }

使用示例二(sqlite3_get_table 方式获取执行结果):

   

#include <sqlite3.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
     
    #define  TABLE_NAME  xxx  //表名
    #define  CARD_ID  xxx //卡ID
    #define  TYPE  xxx //类型
    int main(int argc, char *argv[])
    {
        sqlite3 *pdb;
        int rc = 0; //返回值
        int nrow = 0;       //查询到数据的行数
        int ncolumn = 0;   //查询到数据的列数
        char **azResult;   //二维数组存放结果
        char sql[128]={0};   //sql语句
        char *zErrMsg = NULL; //错误信息
     
        /*step 1: 打开数据库连接对象*/
        rc = sqlite3_open(argv[1], &pdb );
        if (r != SQLITE_OK)
        {
            perror("sqlite3_open error");
            return -1;
        }
     
        /*step 2: sql语句对象。*/
        sqlite3_stmt *pStmt;
        sprintf(sql,"SELECT * FROM %s WHERE cardId = '%s' AND type = %d;", TABLE_NAME, CARD_ID, TYPE );
        
        rc = sqlite3_prepare_v2(
                    pdb, //数据库连接对象
                    sql, //指向原始sql语句字符串
                    strlen(sql) , //
                    &pStmt,
                    NULL
                );
        if (rc != SQLITE_OK)
        {
            perror("sqlite3_prepare_v2 error:");
            return -1;
        }
     
        printf("The SQL CMD:%s\n",sql);
        
        rc = sqlite3_get_table( pdb, sql, &azResult, &nrow, &ncolumn, &zErrMsg ); //查询数据库
        if( rc != SQLITE_OK )
        {
            fprintf(stderr,"Can't get table: %s",sqlite3_errmsg(pdb));
            return -1;
        }
     
        printf( "nrow = %d ,ncolumn = %d\n", nrow, ncolumn ); //打印查询结果表的行数和列数
        if( nrow !=0 && ncolumn != 0 )     //有查询结果,不包含表头所占行数
        {
            int i=0,j=0;
            for(i=0; i<= nrow; i++)           //打印查询结果
            {
                 for(j=0; j<ncolumn; j++)
                 {
                      if(i==0) //第0行为数据表头
                      {
                         printf("%s\t", azResult[i+j]);
                      }
                      else
                         printf("%s\t", azResult[i+j]);
                 }
                 printf("\n");
            }
            
        }
        sqlite3_free_table(azResult);     //释放掉 azResult的内存空间
        
        sqlite3_finalize(pStmt);     //销毁一个SQL语句对象
     
        /*step 3: 关闭数据库连接对象*/
        sqlite3_close(pdb);
     
        return 0;
    }   

二、sqlite3回调形式接口用法

一步到位的函数接口: sqlite3_exec

sqlite3_exec其实是sqlite3_prepare_v2、sqlite3_step、sqlite3_finalize 三个函数的组合。

函数原型及用法:

   

 int sqlite3_exec( sqlite3* , //指向数据库连接对象
                      const char *sql , //指向要执行的SQL语句,一般不带参数。
                      int (*callback) (void *, int, char **, char **), //回调函数
                      void *arg, //这个函数将作为callback的第一个参数传入
                      char **errmsg //用来保存出错的信息        
                    );


    第一个参数,数据库连接对象
     
    第二个参数,要执行的sql语句,可以执行多条语句以;分开
     
    第三个参数,函数指针,回调函数。一般在sql语句为select语句时,需要回调。每查询到一条结果时(一行),就调用该回调函数。
   

 int (*callback)(
                      void *,     //sqlite3_exec的第四个参数
                      int,    //结果中有多少列
                      char **, // char *column_values[],这一行每列的值(转化成字符串)
                      char **  //char *column_names[],这一行每列的名字(字符串)
               ),


    回调函数的返回值: 返回0表示成功,其他值表示失败,回调函数执行失败了(返回非0值),sqlite3_exec就不执行下面的语句了。
     
    第四个参数:将作为回调函数的第一个参数.
     
    第五个参数: *errmsg将保存执行过程中的错误信息。
     
    返回值:  成功返回0, 失败返回其他值。

使用示例:

 

   #include <sqlite3.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
     
    int select_cb(void *data, int cNum, char *column_values[], char *column_names[]) //回调函数,处理sql语句执行结果
    {
        int *p = (int *)data;
        int i;
        if ( *p )
        {
            for (i = 0; i < cNum; i++)
            {
                printf("%s\t", column_names[i]);
            }
            printf("\n");
            *p = 0;
        }
        for (i = 0; i < cNum; i++)
        {
            printf("%s\t",column_values[i]);
        }
        printf("\n");
        return 0;
    }
     
    int main(int argc, char *argv[])
    {
        sqlite3 *pdb;
        int r ;
        /*step 1: 打开数据库连接对象*/
        r = sqlite3_open(argv[1], &pdb );
        if (r != SQLITE_OK)
        {
            perror("sqlite3_open error");
            return -1;
        }
     
        /* sql语句 */
        char *sql=    "SELECT STUINFO.SID,SNAME,CNAME,SCORE\
                        FROM STUINFO, COURCE, SCORE\
                        WHERE STUINFO.SID = SCORE.SID \
                        AND COURCE.CID = SCORE.CID ;";
     
        int first = 1;
        
        /*step 2: 执行sql语句*/
        r = sqlite3_exec(pdb,sql,select_cb,(void*)&first,NULL);
        
        /*step 3: 关闭数据库连接对象*/
        sqlite3_close(pdb);
         
        return 0;
    }

回调形式接口详细可参考: http://www.runoob.com/sqlite/sqlite-c-cpp.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值