嵌入式数据库sqlite3【进阶篇】-如何用C语言操作sqlite3,一文搞懂

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

数据库

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

nonamescore
4一口Linux89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name 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, 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;
 }

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

nonamescore
4一口Linux77.0
5一口peng88.0
6一口wang99.0
7一口网66.0

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

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

数据库

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

nonamescore
4一口Linux89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name 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, 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;
 }

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

nonamescore
4一口Linux77.0
5一口peng88.0
6一口wang99.0
7一口网66.0

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

在这里插入图片描述

由上图可知:
代码中:

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

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

使用回调函数执行SQL语句

sqlite3_exec

typedef  int (*sqlite3_callback)(void *, int, char **, 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 对应结果的列数,为3
f_value 则指向 每一列对应的值组成的字符串数组

假设现在callback是第四次被调用,如下图:
在这里插入图片描述

运行结果

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

gcc student.c -o run -lsqlite3

运行主页面:
在这里插入图片描述

插入记录:
在这里插入图片描述
显示记录:
在这里插入图片描述
删除记录:
在这里插入图片描述

其他函数

sqlite3 *pdb, 数据库句柄,跟文件句柄FILE很类似
sqlite3_stmt *stmt, 这个相当于ODBC的Command对象,用于保存编译好的SQL语句

sqlite3_exec(), 执行非查询的sql语句
sqlite3_prepare(), 准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_exec)
Sqlite3_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, NULL, NULL, &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, NULL, NULL, &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;
	int rc = 0;
	char *errmsg;	
	char clean[64];
/* Create SQL statement */
	char sql[] ="CREATE TABLE IF NOT EXISTS STUDENT(" \
	  "NO INT PRIMARY KEY     NOT NULL," \
	  "NAME           TEXT    NOT NULL," \
	  "SCORE            INT     NOT NULL);";


	if (sqlite3_open("my.db", &db) < 0)
	{
		printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));
		return -1;
	}
	

  /* Execute SQL statement */
	rc = sqlite3_exec(db, sql, NULL, 0, &errmsg);

	if (rc != SQLITE_OK) {
		fprintf(stderr, "SQL error: %s\n", errmsg);
		sqlite3_free(errmsg);
	} else {
		fprintf(stdout, "Table created successfully\n");
	}

	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, 64, stdin);
			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」 ,回复sqlite3

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一口Linux

众筹植发

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值