最近在使用sqlite3执行查询语句的时候遇到了一些问题,虽然老师讲了怎么使用,但还是一知半解,直到返回去看C部分的笔记才恍然大悟。
我们先从sqlite3_exec函数说起。
sqlite3_exec的函数原型
int sqlite3_exec(
sqlite3*, /* 数据库连接 */
const char *sql, /* SQL 语句 */
int (*callback)(void*,int,char**,char**), /* 回调函数 */
void *, /* 回调函数的第一个参数 */
char **errmsg /* 错误信息 */
);
这个函数中sqlite3*是一个指针,传递的是数据库的地址。 第二个参数是sql语句,执行的是和数据库相关的指令,比如"select * from usr"。第三个是回调函数,这个回调函数只有在查询的时候才会起作用。void *用来给回调函数传参。第五个参数用来保存错误信息。
回调函数原型
看完了上面的函数,我们进入正题,来看一下回调函数的原型。
int callback(void *data, int argc, char **argv, char **azColName);
- data:为回调函数传递参数使用的,不使用写为NULL。
- argc:表示结果集的列的个数。
- argv:二级指针,是一个字符串数组,代表结果集中的一行数据(即一行多列的字段值,每一列字段值由一个字符指针指向)
- azColName:二级指针,也是一个字符串数组,表示结果集每一列的列名(即一行的多列的字段名是什么,每一列字段名由一个字符指向指向)
这其中最重要的就是第三个参数,他是一个二级指针。其中存放了结果集中的一行数据。二级指针和指针数组是可以等价的。在这里要分辨出什么是数组指针和指针数组。
数组指针和指针数组
指针数组是一个数组,其中存放的全是指针,示例如下:
该定义说明数组中存放了10个指向int类型的指针。
int *arr[10];
数组指针是一个指向数组的指针,示例如下:
该定义说明了指针指向了存放10个int类型元素的数组。
int (*arr)[10];
回调函数中二级指针的使用
在数据库中,数据是以如图的方式进行存储的。argc是结果集的列的个数,argv是一个指针数组。其中有数个指针,分别指向了数据库中的内容。这样通过调用argv数组,就可以找到数据库中的内容了。
那么这个指针数组是如何遍历的呢?在调用过程中是怎样运行的呢?
我们知道,第三个参数代表了结果集中的一行数据。在回调函数时,需要遍历这个argv指针数组,并将结果转为需要的类型。当使用select调用时,回调函数会回调多次,每回调一次就会查询一次,具体查询几次则由结果集中由多少行决定。比如,我数据库中写了三行数据,那么回调函数就会执行三次。如果结果集为空的话,则回调函数就不会被调用。