掌握C语言操作sqlite3的完全指南

发表时间: 2020-09-22 08:34

sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。



数据库

本篇假设数据库为my.db,有数据表student。

no name score 4 一口Linux 89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary keyname text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);功能:    打开sqlite数据库参数: path: 数据库文件路径 db: 指向sqlite句柄的指针,后面对数据库所有的操作都要依赖这个句柄返回值: 成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);功能: 关闭sqlite数据库      返回值: 成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);功能: 打印错误信息        返回值: 返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table

int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);功能: 执行SQL操作参数: db:数据库句柄 sql:SQL语句 resultp:用来指向sql执行结果的指针 nrow:满足条件的记录的数目 ncolumn:每条记录包含的字段数目 errmsg:错误信息指针的地址返回值: 成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db) {  char **result, *errmsg; int nrow, ncolumn, i, j, indexif (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0) {  printf("error : %s\n", errmsg);  sqlite3_free(errmsg); } index = ncolumn; for (i=0; i<nrow; i++) {  for (j=0; j<ncolumn; j++)  {   printf("%-8s : %-8s\n", result[j], result[index]);      index++;  }  printf("************************\n"); } sqlite3_free_table(result); return; }

假定当前的表格的数据信息如下:

no name score 4 一口Linux 77.0 5 一口peng 88.0 6 一口wang 99.0 7 一口网 66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。

数据库

本篇假设数据库为my.db,有数据表student。

no name score 4 一口Linux 89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary keyname text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);功能:    打开sqlite数据库参数: path: 数据库文件路径 db: 指向sqlite句柄的指针返回值: 成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);功能: 关闭sqlite数据库      返回值: 成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);功能: 打印错误信息        返回值: 返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table

int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);功能: 执行SQL操作参数: db:数据库句柄 sql:SQL语句 resultp:用来指向sql执行结果的指针 nrow:满足条件的记录的数目 ncolumn:每条记录包含的字段数目 errmsg:错误信息指针的地址返回值: 成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db) {  char **result, *errmsg; int nrow, ncolumn, i, j, indexif (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0) {  printf("error : %s\n", errmsg);  sqlite3_free(errmsg); } index = ncolumn; for (i=0; i<nrow; i++) {  for (j=0; j<ncolumn; j++)  {   printf("%-8s : %-8s\n", result[j], result[index]);      index++;  }  printf("************************\n"); } sqlite3_free_table(result); return; }

假定当前的表格的数据信息如下:

no name score 4 一口Linux 77.0 5 一口peng 88.0 6 一口wang 99.0 7 一口网 66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

在这里插入图片描述

由上图可知: 代码中:

ncolumn = 3nrow    = 5result 指向所有的结果组成的字符串数组,各个具体字符串的下标,图上已经标明。

结合此图再去理解代码,就很容易理解代码的实现原理。

使用回调函数执行SQL语句

sqlite3_exec

typedef  int (*sqlite3_callback)(void *, intchar **, char **);int   sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *,  char **errmsg);功能: 执行SQL操作参数: db:数据库句柄 sql:SQL语句,就是我们前面两章用于操作表的增删改查语句 callback:回调函数 errmsg:错误信息指针的地址返回值: 成功返回0,失败返回错误码

回调函数

typedef  int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);功能: 每找到一条记录自动执行一次回调函数参数: para:传递给回调函数的参数 f_num:记录中包含的字段数目 f_value:包含每个字段值的指针数组 f_name:包含每个字段名称的指针数组返回值: 成功返回0,失败返回-1

举例

sqlite3 *db;char  *errmsg,**resultp;int callback(void *para, int f_num, char **f_val, char **f_name)int i; for (i=0; i<f_num; i++) {  printf("%-8s", f_val[i]); } printf("\n"); return 0;}void do_show(sqlite3 *db)char *errmsg; printf("no      name    score\n");  if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0) {  printf("error : %s\n", sqlite3_errmsg(db)); } printf("\n"); return;}

回调函数方法实现的代码,需要实现一个回调函数:callback。 函数sqlite3_exec()在解析命令"select * from student" ,没获取到一行数据就会调用一次回调函数, 参考上面的表格student,

callback()总共会被调用5次,f_num 对应结果的列数,为3f_value 则指向 每一列对应的值组成的字符串数组

假设现在callback是第四次被调用,如下图:

运行结果

编译需要使用第三方库lsqlite3。

gcc student.c -o run -lsqlite3

其他函数

sqlite3 *pdb, 数据库句柄,跟文件句柄FILE很类似sqlite3_stmt *stmt, 这个相当于ODBCCommand对象,用于保存编译好的SQL语句sqlite3_exec(), 执行非查询的sql语句sqlite3_prepare(), 准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_execSqlite3_step(), 在调用sqlite3_prepare后,使用这个函数在记录集中移动

还有一系列的函数,用于从记录集字段中获取数据,如

sqlite3_column_text(), 取text类型的数据sqlite3_column_blob(),取blob类型的数据sqlite3_column_int(), 取int类型的数据

国际惯例,上完整代码:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sqlite3.h>void do_insert(sqlite3 *db)int no; char name[16]; float score; char sqlstr[128], *errmsg; printf("input no : "); scanf("%d", &no); printf("input name : "); scanf("%s", name); printf("input score : "); scanf("%f", &score); sprintf(sqlstr, "insert into student values (%d, '%s', %.1f)",  no, name, score); #if __DEBUG printf("cmd:%s\n",sqlstr); #endif if (sqlite3_exec(db, sqlstr, NULLNULL, &errmsg) != 0) {  printf("error : %s\n", sqlite3_errmsg(db)); } else {  printf("insert is done\n"); } printf("\n"); return;}void do_delete(sqlite3 *db)char *errmsg; char sqlstr[128], expression[64]; printf("input expression : "); scanf("%s", expression);//name='ma' sprintf(sqlstr, "delete from student where %s", expression);#if __DEBUG printf("cmd:%s\n",sqlstr);#endif if (sqlite3_exec(db, sqlstr, NULLNULL, &errmsg) != 0) {  printf("error : %s\n", sqlite3_errmsg(db)); } else {  printf("deletet is done\n"); } printf("\n"); return;} int callback(void *para, int f_num, char **f_val, char **f_name)int i; for (i=0; i<f_num; i++) {  printf("%-8s", f_val[i]); } printf("\n"); return 0;}void do_show(sqlite3 *db)char *errmsg; printf("no      name    score\n"); if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0) {  printf("error : %s\n", sqlite3_errmsg(db)); } printf("\n"); return;} void do_show_sample(sqlite3 *db) {  char **result, *errmsg; int nrow, ncolumn, i, j, index; if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0) {  printf("error : %s\n", errmsg);  sqlite3_free(errmsg); }  index = ncolumn; for (i=0; i<nrow; i++) {  for (j=0; j<ncolumn; j++)  {   printf("%-8s : %-8s\n", result[j], result[index]);          index++;  }  printf("************************\n"); } sqlite3_free_table(result); return; } int main(){ sqlite3 *db; int n; char clean[64]; if (sqlite3_open("my.db", &db) < 0) {  printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));  return -1; } while ( 1 ) {  printf("*********************************************\n");  printf("1: insert record   \n2: delete record  \n3: show record  \n4: quit\n");  printf("*********************************************\n");  printf("please select : ");     if (scanf("%d", &n) != 1)  {   fgets(clean, 64stdin);   printf("\n");   continue;  }  switch ( n )  {   case 1 :    do_insert(db);    break;   case 2 :    do_delete(db);    break;   case 3 :    do_show_sample(db);    break;   case 4 :    sqlite3_close(db);    exit(0);  } } return 0;}

运行主页面:

插入记录:

显示记录:

删除记录:

完整代码,请关注公众号「一口Linux」