基于SQLite数据库的学生管理系统-C语言

基于SQLite数据库的学生管理系统

SQLite数据库用法SQLite

错误信息获取

全文使用
sqlite3_exec(sql_db, buff, NULL, NULL, NULL) printf("errmsg[%s]\n",sqlite3_errmsg(sql_db))

代码实现

student_system.c

#include "./my_sqlite3.h"

//打印功能菜单
void print_menu()
{
	printf("--------------------------------------------------\n");
	printf("|  1.添加  2.删除  3.修改  4.查询所有学员  5.退出|\n");
	printf("--------------------------------------------------\n");
	printf("输入您的选择 : ");
}
int main(int argc, const char *argv[])
{
	//      句柄---数据库初始化
	sqlite3 *sql_db = proc_init();

	int choose = 0; // 选择
	while (1)
	{
		print_menu();		  // 打印功能菜单
		scanf("%d", &choose); // 输入选择

		switch (choose)
		{
		case 1:
			insert_student(sql_db); // 添加
			break;
		case 2:
			delete_student(sql_db); // 删除
			break;
		case 3:
			update_student(sql_db); // 修改
			break;
		case 4:
			// search_student1(sql_db); // 查询所有学员---方法 1 :sqlite3_get_table
			search_student2(sql_db); // 查询所有学员---方法 2 :callback 回调函数
			break;
		case 5:
			break;
		default:
			printf("输入错误,只支持输入[1~5]\n");
			break;
		}
		if (5 == choose)
		{
			break;
		}
	}

	//关闭sqlite3 句柄
	sqlite3_close(sql_db);

	return 0;
}

// 1. 数据库初始化 ---打开数据文件、建表
sqlite3 *proc_init(void)
{
	sqlite3 *sql_db = NULL;
	//打开一个数据库文件,存在直接打开 不存在 新建并打开
	int ret = sqlite3_open("NO1.db", &sql_db);
	if (ret != SQLITE_OK)
	{
		perror("打开数据库文件 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}

	//建表
	/*
	IF NOT EXISTS  表不存在则创建 ;表存在则直接使用,而不会报错
	引号里面sql语句后面不用加分号
	*/
	char sql_buff[256] = "CREATE TABLE IF NOT EXISTS student(id INT PRIMARY KEY, name CHAR, score INT)";
	//执行sql语句
	ret = sqlite3_exec(sql_db, sql_buff, NULL, NULL, NULL);
	if (ret != SQLITE_OK)
	{
		perror("建表 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}

	return sql_db;
}

// 1. 添加
void insert_student(sqlite3 *sql_db)
{
	int id, score, ret;
	char name[32];
	printf("输入 ID 姓名 成绩 : ");
	scanf("%d %s %d", &id, name, &score);
	char sql_buff[256] = {0};
	//填写sql语句
	/*
	在代码中组装的sql语句本身就是一个字符串  如果某个字段的值是字符串类型
	就需要用 单引号 '' 引起来 		引号里面sql语句后面不用加分号
	*/
	sprintf(sql_buff, "INSERT INTO student VALUES(%d,'%s',%d)", id, name, score);
	//执行sql语句
	ret = sqlite3_exec(sql_db, sql_buff, NULL, NULL, NULL);
	if (ret != SQLITE_OK)
	{
		perror("添加 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}
	printf("学员信息添加成功\n");
	return;
}
// 2. 删除
void delete_student(sqlite3 *sql_db)
{
	int id, ret;
	printf("输入需要删除 ID : ");
	scanf("%d", &id);
	char sql_buff[256] = {0};
	//填写sql语句
	sprintf(sql_buff, "DELETE FROM student WHERE id=%d", id);
	//执行sql语句
	ret = sqlite3_exec(sql_db, sql_buff, NULL, NULL, NULL);
	if (ret != SQLITE_OK)
	{
		perror("删除 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}
	printf("学员信息删除成功\n");
	return;
}
// 3. 修改
void update_student(sqlite3 *sql_db)
{
	int id, score, ret;
	char name[32];
	printf("输入修改ID 更新姓名 成绩 : ");
	scanf("%d %s %d", &id, name, &score);
	char sql_buff[256] = {0};
	//填写sql语句
	/*
	在代码中组装的sql语句本身就是一个字符串  如果某个字段的值是字符串类型
	就需要用 单引号 '' 引起来  引号里面sql语句后面不用加分号
	*/
	sprintf(sql_buff, "UPDATE student SET name='%s',score=%d WHERE id=%d", name, score, id);
	//执行sql语句
	ret = sqlite3_exec(sql_db, sql_buff, NULL, NULL, NULL);
	if (ret != SQLITE_OK)
	{
		perror("修改 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}
	printf("学员信息修改成功\n");
	return;
}

// 4. 查询所有学员---方法 1 :sqlite3_get_table
void search_student1(sqlite3 *sql_db)
{
	int ret;
	char sql_buff[256] = {0};
	//填写sql语句
	sprintf(sql_buff, "SELECT * FROM student");

	char **result;	// 结果集
	int row = 0;	// 行数
	int column = 0; // 列数
					/*
					会将 查询的到的结果的 行数写到row的地址里  列数写到column的地址里
					让 result 指向 sqlite3_get_table 申请的结果集的内存空间
					*/
	//查询结果的函数                   /结果集 /行数 /列数   /错误信息
	sqlite3_get_table(sql_db, sql_buff, &result, &row, &column, NULL);
	if (ret != SQLITE_OK)
	{
		perror("查询 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}
	/*---------------- 打印学员信息 ----------------*/
	//打印表头
	int i = 0;
	for (i = 0; i < column; i++) // 列数
	{
		printf("%10s", result[i]);
	}
	printf("\n");

	int keep_i = i; // 继续获取 结果集result[ ]内容

	int j = 0;
	for (j = 0; j < row; j++) //行数
	{
		for (i = 0; i < column; i++) // 列数
		{
			printf("\t%s", result[keep_i]);
			keep_i++;
		}
		printf("\n");
	}

	printf("学员信息查询成功\n");
	//释放 结果集 防止内存泄漏
	sqlite3_free_table(result);
	return;
}

// 4. 查询所有学员---方法 2 :callback 回调函数
int flag = 0; // 全局变量 标记表头是否打印
//回调函数
int callback(void *arg, int ncolumn, char **f_value, char **f_name)
{
	//每查询到一条记录 这个函数就会被调用一次
	//打印表头
	int i = 0;
	if (0==flag)
	{
		for (i = 0; i < ncolumn; i++)
		{
			printf("%10s", f_name[i]);
		}
		printf("\n");
		flag=1; //打印之后 将标记flag=1  下次调用就不打印
	}
	//打印字段的值
	for (i = 0; i < ncolumn; i++)
		{
			printf("\t%s", f_value[i]);
		}
		printf("\n");

	return 0; //必须写返回值 否则报错
}
//
void search_student2(sqlite3 *sql_db)
{
	int ret;
	char sql_buff[256] = {0};
	//填写sql语句
	sprintf(sql_buff, "SELECT * FROM student");
	//执行sql语句                         /回调函数
	ret = sqlite3_exec(sql_db, sql_buff, callback, NULL, NULL);
	if (ret != SQLITE_OK)
	{
		perror("查询 失败");
		printf("返回值[%d]  错误信息[%s]\n", ret, sqlite3_errmsg(sql_db));
		exit(-1);
	}
	printf("学员信息查询成功\n");
	flag = 0; //查询结束后 将标记flag = 0 方便下次查询使用
	return;
}

my_sqlite3.h

#ifndef __MY_SQLITE_H__
#define __MY_SQLITE_H__

#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>

// 1. 数据库初始化 ---打开数据文件、建表
sqlite3 *proc_init(void);

// 1. 添加
void insert_student(sqlite3 *sql_db);

// 2. 删除
void delete_student(sqlite3 *sql_db);

// 3. 修改
void update_student(sqlite3 *sql_db); 

// 4. 查询所有学员---方法 1 :sqlite3_get_table
void search_student1(sqlite3 *sql_db); 

// 4. 查询所有学员---方法 2 :callback 回调函数
void search_student2(sqlite3 *sql_db);

#endif

执行结果

在这里插入图片描述

注意

1. 数据库初始化
建表
IF NOT EXISTS不存在则创建 表存在则直接使用,而不是报错

2. 添加
组装sql语句
双引号里面sql语句后面不用加分号
在代码中组装的sql语句本身就是一个字符串 如果某个字段的值是字符串类型
就需要用 单引号 ' ' 引起来 ;

3. 对于删除的语句
即使 记录中没有满足 WHERE后面条件的
语句也会执行成功,只不过没有任何事情发生

4. 对于修改的语句
即使 记录中没有满足 WHERE后面条件的
语句也会执行成功,只不过没有任何事情发生

5.查询使用callback 回调函数
每查询到一条记录 callback 函数就会被调用一次

sqlite3_get_table()函数的 result 结果集

数据
在这里插入图片描述

  • result
    在这里插入图片描述
*查询结果为空时
				row = 0	 		*行数为0
				column = 0;  	*列数为0
	

sqlite3_exec的回调函数—callback

int (*callback)(void* arg ,int  ncolumn ,char** f_value,char** f_name)
功能:
	得到查询结果
参数:	
	arg 	 为回调函数传递参数使用的 --传递多个参数,使用结构体传参
	ncolumn  记录中包含的字段的数目   --表的结构 字段数
	f_value  包含每个字段值的指针数组 --字段值
	f_name   包含每个字段名称的指针数组-字段名(表头)
返回值:
	成功 0
	出错 非0

callback 中的 f_value 和 f_name

f_value 和 f_name 都是指针数组,数组中的每个成员都是一个 char * 指针

数据
在这里插入图片描述

  • callback回调函数 每当查询到一条记录 都会被调用用一次:
    在这里插入图片描述
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值