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

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

https://blog.csdn.net/fangye945a/article/details/86484547

2019年01月15日 00:04:50 fangye945a 阅读数:450

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

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

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

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

 
  1. int sqlite3_open(const char *filename, sqlite3 **ppDb);

  2. filename:要打开的sqlite3数据库的路径名

  3. ppDb: 二级指针,用来保存打开的数据库的连接对象。

  4. 返回值: 成功返回SQLITE_OK,失败返回其他值。

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

int sqlite3_close(sqlite3*);

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

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

 
  1.  int sqlite3_prepare_v2(

  2.       sqlite3 *db,           // 数据库连接对象

  3.       const char *zSql,      // 指向原始sql语句(要编译的sql语句),可以包含变量名的

  4.       int nByte,             // < 0: 编译zSql到第一个\0为止

  5.                  // >0: 编译zSql中前面nByte个字符

  6.                  // =0: 什么也不编译

  7. sqlite3_stmt **ppStmt, // *ppStmt用来保存编译好的sql语句对象

  8.       const char **pzTail    // *pzTail如果不为空,则*pzTail指向zSql中编译的第一条完整sql语句后面的第一个字符。                 

  9.     );

  10.     返回值:成功返回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中的索引。

函数原型:     

 
  1. int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

  2. 返回值:成功返回索引值(>0),假如没有匹配的参数名找到,则返回0

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

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

 
  1. int sqlite3_bind_double(sqlite3_stmt*, int , double);

  2. int sqlite3_bind_int(sqlite3_stmt *, int , int);

  3. 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指定),每次返回一行执行结果。

函数原型及用法:

 
  1. int sqlite3_step(sqlite3_stmt*);

  2. sqlite3_stmt:指向编译好的要执行的SQL语句对象

  3. 返回值: SQLITE_BUSY: 没获取到锁,语句没执行。

  4.        SQLITE_DONE: sql语句执行完成。

  5.        SQLITE_ERROR: 出错啦

  6.        SQLITE_MISUSE: 使用方法不当

  7.        SQLITE_ROW: 假如SQL语句执行有返回结果,SQLITE_ROW返回。然后调用者调用sqlite3_column解析结果。        

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

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

 
  1. int sqlite3_column_count(sqlite3_stmt *pStmt);   //返回结果行中有多少列        

  2. int sqlite3_column_type(sqlite3_stmt *pStmt, int iCol);  //返回结果行中第iCol列的数据类型

  3. 返回值: SQLITE_INTEGER :整数类型

  4.         SQLITE_FLOAT: 浮点类型

  5.         SQLITE_TEXT: 文本类型,char *

  6.         SQLITE_BLOB: blob

  7.         SQLITE_NULL: 空类型

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

 
  1. const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

  2. int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

  3. int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);

  4. const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);

  5. const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);

  6. double sqlite3_column_double(sqlite3_stmt*, int iCol);

  7. int sqlite3_column_int(sqlite3_stmt*, int iCol);

  8. long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);

  9. const char *sqlite3_column_name(sqlite3_stmt*, int iCol);

  10. const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);

  11. const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

  12. const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

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

函数原型为:

 
  1. int sqlite3_get_table(

  2. sqlite3 *db, /* An open database */

  3. const char *zSql, /* SQL to be evaluated */

  4. char ***pazResult, /* Results of the query */

  5. int *pnRow, /* Number of result rows written here */

  6. int *pnColumn, /* Number of result columns written here */

  7. char **pzErrmsg /* Error msg written here */

  8. );

  9. 第1个参数为数据库连接对象。

  10. 第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾的char*字符串。

  11. 第3个参数是查询结果(可理解为二维数组的地址)。

  12. 第4个参数是查询出多少条记录(即查出多少行,不包括字段名那行)。

  13. 第5个参数是多少个字段(多少列)。

  14. 第6个参数是错误信息

  15. 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 方式获取执行结果):

 
  1. #include <sqlite3.h>

  2. #include <stdio.h>

  3. #include <string.h>

  4. #include <errno.h>

  5.  
  6. int main(int argc, char *argv[])

  7. {

  8. sqlite3 *pdb;

  9. int r ;

  10. /*step 1: 打开数据库连接对象*/

  11. r = sqlite3_open(argv[1], &pdb );

  12. if (r != SQLITE_OK)

  13. {

  14. perror("sqlite3_open error");

  15. return -1;

  16. }

  17. /*step 2: sql语句对象。*/

  18. sqlite3_stmt *pStmt;

  19. char *sql= "SELECT STUINFO.SID,SNAME,CNAME,SCORE\

  20. FROM STUINFO, COURCE, SCORE\

  21. WHERE STUINFO.SID = SCORE.SID \

  22. AND COURCE.CID = SCORE.CID ;";

  23. r = sqlite3_prepare_v2(

  24. pdb, //数据库连接对象

  25. sql, //指向原始sql语句字符串

  26. strlen(sql) , //

  27. &pStmt,

  28. NULL

  29. );

  30. if (r != SQLITE_OK)

  31. {

  32. perror("sqlite3_prepare_v2 error:");

  33. return -1;

  34. }

  35. while (1)

  36. {

  37. static int first = 1;

  38. int i;

  39. /*2.2 执行SQL语句*/

  40. r = sqlite3_step(pStmt);

  41. if (r == SQLITE_DONE)

  42. {

  43. printf("o la\n");

  44. break;//执行完成

  45. }

  46. else if (r == SQLITE_ROW) //获取到一行的结果

  47. {

  48. int cNum =0 ;//结果集中有多少列

  49. cNum = sqlite3_column_count(pStmt);

  50. if (first)

  51. {

  52. for (i = 0; i < cNum; i++)

  53. {

  54. //返回结果集中第i列的名字

  55. const char *p = sqlite3_column_name(pStmt, i);

  56. printf("%s\t", p);

  57. }

  58. printf("\n---------------------------\n");

  59. first = 0;

  60. }

  61. int iType; //第i列的数据类型

  62. for (i = 0; i < cNum; i++)

  63. {

  64. //获取结果集中第i列的数据类型

  65. iType = sqlite3_column_type(pStmt, i);

  66. if (iType == SQLITE_INTEGER)

  67. {

  68. int iValue;

  69. //获取结果集中第i列的数据值

  70. iValue = sqlite3_column_int(pStmt, i);

  71. printf("%d\t", iValue);

  72. }else if (iType == SQLITE_FLOAT)

  73. {

  74. double iValue;

  75. //获取结果集中第i列的数据值

  76. iValue = sqlite3_column_double(pStmt, i);

  77. printf("%g\t", iValue);

  78.  
  79.  
  80. }else if (iType == SQLITE_TEXT)

  81. {

  82. const char * iValue;

  83. //获取结果集中第i列的数据值

  84. iValue = sqlite3_column_text(pStmt, i);

  85. printf("%s\t", iValue);

  86. }

  87. }

  88. printf("\n");

  89. }

  90. }

  91. //销毁一个SQL语句对象

  92. sqlite3_finalize(pStmt);

  93.  
  94. /*step 3: 关闭数据库连接对象*/

  95. sqlite3_close(pdb);

  96. return 0;

  97. }

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

 
  1. #include <sqlite3.h>

  2. #include <stdio.h>

  3. #include <string.h>

  4. #include <errno.h>

  5.  
  6. #define TABLE_NAME xxx //表名

  7. #define CARD_ID xxx //卡ID

  8. #define TYPE xxx //类型

  9. int main(int argc, char *argv[])

  10. {

  11. sqlite3 *pdb;

  12. int rc = 0; //返回值

  13. int nrow = 0; //查询到数据的行数

  14. int ncolumn = 0; //查询到数据的列数

  15. char **azResult; //二维数组存放结果

  16. char sql[128]={0}; //sql语句

  17. char *zErrMsg = NULL; //错误信息

  18.  
  19. /*step 1: 打开数据库连接对象*/

  20. rc = sqlite3_open(argv[1], &pdb );

  21. if (r != SQLITE_OK)

  22. {

  23. perror("sqlite3_open error");

  24. return -1;

  25. }

  26.  
  27. /*step 2: sql语句对象。*/

  28. sqlite3_stmt *pStmt;

  29. sprintf(sql,"SELECT * FROM %s WHERE cardId = '%s' AND type = %d;", TABLE_NAME, CARD_ID, TYPE );

  30.  
  31. rc = sqlite3_prepare_v2(

  32. pdb, //数据库连接对象

  33. sql, //指向原始sql语句字符串

  34. strlen(sql) , //

  35. &pStmt,

  36. NULL

  37. );

  38. if (rc != SQLITE_OK)

  39. {

  40. perror("sqlite3_prepare_v2 error:");

  41. return -1;

  42. }

  43.  
  44. printf("The SQL CMD:%s\n",sql);

  45.  
  46. rc = sqlite3_get_table( pdb, sql, &azResult, &nrow, &ncolumn, &zErrMsg ); //查询数据库

  47. if( rc != SQLITE_OK )

  48. {

  49. fprintf(stderr,"Can't get table: %s",sqlite3_errmsg(pdb));

  50. return -1;

  51. }

  52.  
  53. printf( "nrow = %d ,ncolumn = %d\n", nrow, ncolumn ); //打印查询结果表的行数和列数

  54. if( nrow !=0 && ncolumn != 0 ) //有查询结果,不包含表头所占行数

  55. {

  56. int i=0,j=0;

  57. for(i=0; i<= nrow; i++) //打印查询结果

  58. {

  59. for(j=0; j<ncolumn; j++)

  60. {

  61. if(i==0) //第0行为数据表头

  62. {

  63. printf("%s\t", azResult[i+j]);

  64. }

  65. else

  66. printf("%s\t", azResult[i+j]);

  67. }

  68. printf("\n");

  69. }

  70.  
  71. }

  72. sqlite3_free_table(azResult); //释放掉 azResult的内存空间

  73.  
  74. sqlite3_finalize(pStmt); //销毁一个SQL语句对象

  75.  
  76. /*step 3: 关闭数据库连接对象*/

  77. sqlite3_close(pdb);

  78.  
  79. return 0;

  80. }

二、sqlite3回调形式接口用法

一步到位的函数接口: sqlite3_exec

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

函数原型及用法:

 
  1. int sqlite3_exec( sqlite3* , //指向数据库连接对象

  2.              const char *sql , //指向要执行的SQL语句,一般不带参数。

  3.              int (*callback) (void *, int, char **, char **), //回调函数

  4.              void *arg, //这个函数将作为callback的第一个参数传入

  5.              char **errmsg //用来保存出错的信息        

  6.          );

  7. 第一个参数,数据库连接对象

  8.  
  9. 第二个参数,要执行的sql语句,可以执行多条语句以;分开

  10.  
  11. 第三个参数,函数指针,回调函数。一般在sql语句为select语句时,需要回调。每查询到一条结果时(一行),就调用该回调函数。

  12. int (*callback)(

  13.  void *,     //sqlite3_exec的第四个参数

  14.                   int,    //结果中有多少列 

  15.                   char **, // char *column_values[],这一行每列的值(转化成字符串)

  16.                   char **  //char *column_names[],这一行每列的名字(字符串)

  17.            ), 

  18. 回调函数的返回值: 返回0表示成功,其他值表示失败,回调函数执行失败了(返回非0值),sqlite3_exec就不执行下面的语句了。

  19.  
  20. 第四个参数:将作为回调函数的第一个参数.

  21.  
  22. 第五个参数: *errmsg将保存执行过程中的错误信息。

  23.  
  24. 返回值:  成功返回0, 失败返回其他值。

使用示例:

 
  1. #include <sqlite3.h>

  2. #include <stdio.h>

  3. #include <string.h>

  4. #include <errno.h>

  5.  
  6. int select_cb(void *data, int cNum, char *column_values[], char *column_names[]) //回调函数,处理sql语句执行结果

  7. {

  8. int *p = (int *)data;

  9. int i;

  10. if ( *p )

  11. {

  12. for (i = 0; i < cNum; i++)

  13. {

  14. printf("%s\t", column_names[i]);

  15. }

  16. printf("\n");

  17. *p = 0;

  18. }

  19. for (i = 0; i < cNum; i++)

  20. {

  21. printf("%s\t",column_values[i]);

  22. }

  23. printf("\n");

  24. return 0;

  25. }

  26.  
  27. int main(int argc, char *argv[])

  28. {

  29. sqlite3 *pdb;

  30. int r ;

  31. /*step 1: 打开数据库连接对象*/

  32. r = sqlite3_open(argv[1], &pdb );

  33. if (r != SQLITE_OK)

  34. {

  35. perror("sqlite3_open error");

  36. return -1;

  37. }

  38.  
  39. /* sql语句 */

  40. char *sql= "SELECT STUINFO.SID,SNAME,CNAME,SCORE\

  41. FROM STUINFO, COURCE, SCORE\

  42. WHERE STUINFO.SID = SCORE.SID \

  43. AND COURCE.CID = SCORE.CID ;";

  44.  
  45. int first = 1;

  46.  
  47. /*step 2: 执行sql语句*/

  48. r = sqlite3_exec(pdb,sql,select_cb,(void*)&first,NULL);

  49.  
  50. /*step 3: 关闭数据库连接对象*/

  51. sqlite3_close(pdb);

  52.  
  53. return 0;

  54. }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值