深⼊理解SQLite3之sqlite3_exec及回调函数
sqlite3的C/C++接⼝API主要有3个重要函数,分别为
11、sqlite3_open(const char* filename, sqlite3 **ppDb);
22、int 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
103、sqlite3_close(sqlite3*)
sqlite3_open和sqlite3_close是很好理解的,分别是打开和关闭对应的数据库。⽽sqlite3_exec函数是sqlite3的API函数,可以实现各种功能,所以理解sqlite3_exec对于实际的 编程⼗分有必要,我们来详细分析sqlite3_exec函数,
1、sqlite3_exec函数 形参
1sqlite3* : open 打开的数据库
2const char* sql, : 执⾏的sql功能语句
3*callback, : sql语句对应的回调函数
4void* data, : 传递给回调函数的指针参数
5char **errmsq : 错误信息
其中 const char* sql表⽰ 相应的 sql语句,如果我们直接在linux下,使⽤shell是可以实现所有的sqlite功能的,但是如果进⾏C或C++开发程序时,很明显是没有shell可⽤的,所以这个 *sql就是对应sqlite
功能命令的 “字符串”,后⾯我们举例来分析。回调函数指针callback则是 *sql功能命令对应的 回调函数,所谓 回调函数的意思是,会先执⾏*sql对应的功能命令,然后将结果传递给回调函数,回调函数根据结果再进⼀步执⾏。这代表着,这个 “回调函数”才是最有意义的,我们要讲我们需要的功能,通过回调函数来实现,不管是获取数据库表中有效信息,还是其他动作。
2、sqlite3_exec的回调函数 callback
我们还是来先看下回调函数的参数:
1typedef int(*sqlite_callback)(void* para, int columenCount, char** columnValue, char** columnName);
2
3参数:
4para : 由sqlite3_exec传⼊的参数指针,或者说是指针参数
columnCount: 查询到的这⼀条记录由多少个字段(多少列)
1columnValue : 该参数是双指针,查询出来的数据都保存在这⾥,它是⼀个1维数组,每⼀个元素都是⼀
2个char*,是⼀个字段内容,所以这个参数就可以不是单字节,⽽是可以为字符串等不定
3长度的数值,⽤字符串表⽰,以'\0'结尾。
4
1columnName : 该参数是双指针,语columnValue是对应的,表⽰这个字段的字段名称,
2
3返回 : 执⾏成果则返回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
5static int callback(void *data, int argc, char **argv, char **azColName){
6 int i;
7 fprintf(stderr, "%s: ", (const char*)data);
8 for(i=0; i<argc; i++){
9 printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
10 }
11 printf("\n");
12 return 0;
13}
14
15int main(int argc, char* argv[])
16{
17 sqlite3 *db;
18 char *zErrMsg = 0;
19 int rc;
20 char *sql;
21 const char* data = "Callback function called";
22
23 /* Open database */
24 rc = sqlite3_open("test.db", &db);
25 if( rc ){
26 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
27 exit(0);
28 }else{
29 fprintf(stderr, "Opened database successfully\n");
30 }
31
32 /* Create SQL statement */
33 sql = "SELECT * from COMPANY";
34
35 /* Execute SQL statement */
36 rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
37 if( rc != SQLITE_OK ){
38 fprintf(stderr, "SQL error: %s\n", zErrMsg);
39 sqlite3_free(zErrMsg);
40 }else{
41 fprintf(stdout, "Operation done successfully\n");
42 }
43 sqlite3_close(db);
44 return 0;
45}
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 );";
所以执⾏的结果:
1Opened database successfully
2Callback function called: ID = 1
3NAME = Paul
4AGE = 32
5ADDRESS = California
6SALARY = 20000.0
7
8Callback function called: ID = 2
9NAME = Allen
10AGE = 25
11ADDRESS = Texas
12SALARY = 15000.0
13
14Callback function called: ID = 3
15NAME = Teddy
16AGE = 23
17ADDRESS = Norway
18SALARY = 20000.0
19
20Callback function called: ID = 4
21NAME = Mark
fprintf作用22AGE = 25
23ADDRESS = Rich-Mond
24SALARY = 65000.0
25
26Operation done successfully
可以看出来,由于sql命令⾏为 select* from COMPANY,该命令会将表中所有信息都输出,总共5个字段(列),包含4条信息(⾏),所以这个回调函数会被执⾏4次,理解这个逻辑,⾮常重要。
⽽且回调函数的后两个参数是 双指针 ,也就是 指针的指针,包含了2层的指向,⾥层的 指向是 对应具体的数据指针,外层的指向则是 数据指针序号,也可以理解成 “列”索引。我们通过这两个指针能够进⼀步 编写 ⾃定义功能代码。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论