数据库操作以及数据库实现学生管理系统

最近学习了数据库的简单操作,用到的数据库版本是sqlite3,并且运用数据库知识进行了学生管理系统的建立与操作,在这里分享我的所学所得:​​​​​​​

目录

一、首先在Ubuntu中安装sqlite数据库

二、打开数据库文件

三、sqlite3数据库的操作

四、使用sqlite3实现学生管理系统​​​​​​​

        

一、首先在Ubuntu中安装sqlite数据库

        1.离线安装:

                sudo dpkg -i libsqlite3-dev_3.22.0-1ubuntu0.4_amd64.deb sqlite3_3.22.0-1ubuntu0.4_amd64.deb

        2.在线安装:

                sudo apt-get install sqlite3 libsqlite3-dev

        3.如何确定是否安装成功

                在Ubuntu终端输入sqlite3,如果出现以下界面说明安装成功可以使用:

二、打开数据库文件

           4.打开数据库的方式有两种:

                (1)sqlite3 数据库文件名        (数据库文件名一般以 .db 结尾)

                (2)先输入命令 sqlite3 进入sqlite命令行

                         再使用 .open 数据库文件名 打开       

                        (数据库文件名一般以 .db 结尾  .open前有一个点符号不要忽略)

三、sqlite3数据库的操作

        1.系统命令

                sqlite3的系统命令都是以 . 开头,结尾不能加分号

                不同的数据库系统命令一般不同

                一般常用的sqlite3命令如下:

.help			打开帮助文档
.open			打开数据库文件
.quit			退出数据库程序  也可以是  .q
.exit			退出数据库程序
.tables			查看当前数据库文件中有哪些数据表
.schema			查看建表语句(表结构)的
.headers on|off	查询时是否显示表头信息

                关于数据库文件、数据表、字段、表结构解释如图:

                其中:学生信息表、任课教师表、学生成绩表:同一数据库文件(.db)中的多个数据表

                           id、name、sex :表的字段

                           1001、小马、89 :表中的一条记录

                           表结构就是如图所示这样,类似于一个excel表格

        2.SQL语句

                SQL语句是用来操作数据库文件的(增删改查等)

                虽然不同数据库的系统命令不同,但是关系型数据库的SQL语句都是通用的。

                SQL语句的关键字不分大小写,只是一般情况下关键字都是大写。

                SQL语句和SQL命令相反   不以 . 开头,但是以 ;结尾。

        具体SQL简单语句如下:

1.创建数据表(创建数据库文件时候,不会自动创建数据表,需要我们手动创建)
    CREATE TABLE 表名(字段1 字段1类型, 字段2 字段2类型,..., 字段n 字段n类型);
        字段类型:
                整型        INT或者INTEGER
                字符串      CHAR或者TEXT
    例:
    CREATE TABLE student(id INT, name CHAR, score INTEGER);
2.向表中插入数据
    //1.完全赋值  这种方式需要要求必须从左到右给表的每个字段都赋值
    INSERT INTO student VALUES(1001, "小关", 90);

    //2.部分赋值  这种方式可以给指定的字段插入数据
    INSERT INTO student(id,name) VALUES(1002,"小马");
3.查询表中的数据
    //查询表中的所有字段以及信息记录
    SELECT FROM student;

    //只查询 id 和 name 字段    (将id,name 换成score也是一样的效果)
    SELECT id,name FROM student; 

    //查询score为90的记录的所有字段
    SELECT * FROM student WHERE score=90;

    //查询name是 "小马" 的记录的所有字段    当执行SQL语句时,字符串要加上双引号或者单引号
    SELECT * FROM student WHERE name="小马";

    //也可以在查询时候用上 AND 和 OR 连接多个条件    AND为并且  OR为或者
    SELECT * FROM student WHERE name="小关" AND score=90;
    SELECT * FROM student WHERE score=90 OR score=100;
    
    //查询的同时排序使用 ORDER BY 后跟排序要依据的数据
    SELECT * FROM student ORDER BY score;//根据成绩排序(默认升序)
    //排序也可以在SQL语句末尾处加上 ASC代表升序  DESC代表降序
    //如果没加 默认为升序
4.修改表中的记录
    //将表中 id 为1001 的成员的 score 修改为100
    UPDATE student SET score=100 WHERE id=1001;
    //注:修改命令的条件即使不成立(例如 修改一个不存在的成员的成绩) 也可以执行成功 但是看不到现象
    
    //可以多个条件一起用    
    //将name为小关的成员的score修改为90,id修改为1099
    UPDATE student SET score=90,id=1099 WHERE name="小关";
5.删除表中的记录
    //在表中删除 name 为张三的记录
	DELETE FROM student WHERE name='张三';
	//注:即使条件不成立 也能执行成功 但是看不到现象 和修改表中记录一样

	//多个条件一起用
    //在表中删除 name 为张三的 或者 score为60 的记录
	DELETE FROM student WHERE name="赵六" OR score=60;
6.删除数据表
    DROP TABLE 表名;

        3.sqlite3常用API接口

                注意:sqlite3函数的头文件为 sqlite3.h

                           编译时需要链接sqlite3的库  -lsqlite3

                常用API接如下:

1.打开数据库文件:
    函数原型:
        int sqlite3_open(const char *filename,     /* Database filename (UTF-8) */
                         sqlite3 **ppdb);          /* OUT: SQLite db handle */  
    功能:
        打开一个数据库文件(存在直接打开  不存在就新建并打开)
    参数:
        filename   数据库名字
        ppdb       操作数据库的指针,数据库句柄
    返回值:
        成功返回 SQLITE_OK
        失败返回 error_code

2.获取错误信息的函数
	函数原型:
        const char *sqlite3_errmsg(sqlite3* db);
	功能:
        获取最后一次错误信息描述
3.执行sql语句的函数
	函数原型:
        int sqlite3_exec(sqlite3* db, const char *sql, 
				int (*callback)(void*,int,char**,char**),
				void * arg,  char **errmsg);	
	功能:
		执行sql语句
	参数:
		db		数据库的句柄指针
		sql		将要被执行sql语句
		callback 回调函数, 只有在查询语句时使用 其他情况可以传NULL
		arg		为callback 传参的,如果不是查询语句 也可以传NULL
		errmsg	错误信息的地址
				(如果使用了这个参数,要记得使用 sqlite3_free 去释放空间)
	返回值:
		成功返回SQLITE_OK
		失败返回errcode 错误码
4.关于sqlite3_exec函数的回调函数callback
	函数原型:
        int callback(void* arg ,int  ncolumn ,char** f_value,char** f_name)
	功能:
		得到查询结果f_value f_name
	参数:	
		arg  	 为回调函数传递参数使用的 不需要参数可以传NULL
		ncolumn  记录中包含的字段的数目
		f_value  包含每个字段值的指针数组
		f_name   包含每个字段名称的指针数组
	返回值:
		成功返回0
		失败返回非0

5.获取查询结果的函数
	函数原型:    
        int sqlite3_get_table(sqlite3 *db, const char *zSql, char ***pazResult, 
				int *pnRow, int *pnColumn, char **pzErrmsg);
	功能:
		查询数据库,它会创建一个新的内存区域来存放查询的结果信息
	参数:
		db		数据库操作句柄
		zSql	数据库的sql语句
		azResult 查询的结果
		nRow     行数
		nColumn  列数
		errmsg   错误消息
	返回值:
	    成功返回0
        失败返回错误码errcode

//用此函数必须使用指定函数进行释放
//释放由sqlite3_get_table产生的结果集
    函数原型:
        sqlite3_free_table(azResult);

4.关闭数据库的函数
    函数原型:
        int sqlite3_close(sqlite3* db);
    功能:
        关闭一个数据库

四、使用sqlite3实现学生管理系统

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

#define DATABASE "hqyj.db"

//进程初始化的函数
int proc_init(sqlite3** p)
{
    //打开数据文件
    int ret = 0;
    char* errmsg = NULL;
    if (SQLITE_OK != (ret = sqlite3_open(DATABASE, p))) {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(*p));
        exit(-1);
    }
    printf("数据库文件打开成功..\n");
    //尝试创建数据表
    //代码中sql语句可以不写分号
    // IF NOT EXISTS 表示 如果不存在则创建 如果存在 则直接打开而不是报错
    char sqlstr[256] = "CREATE TABLE IF NOT EXISTS student(id INT PRIMARY KEY, name CHAR, score INT)";
    if (SQLITE_OK != (ret = sqlite3_exec(*p, sqlstr, NULL, NULL, &errmsg))) {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
            __FILE__, __LINE__, ret, errmsg);
        exit(-1);
    }
    printf("数据表打开成功..\n");
    //释放errmsg
    sqlite3_free(errmsg);
    return 0;
}

//添加学员信息的函数
void insert_student(sqlite3* my_db)
{
    int input_id = 0;
    char input_name[32] = { 0 };
    int input_score = 0;
    printf("请输入新学员的id(INT):");
    scanf("%d", &input_id);
    printf("请输入新学员的name(CHAR):");
    scanf("%s", input_name);
    printf("请输入新学员的score(INT):");
    scanf("%d", &input_score);

    //组装sql语句
    int ret = 0;
    char sqlstr[256] = { 0 };
    //在字符串的sql语句中再想使用引号时 使用单引号即可
    sprintf(sqlstr, "INSERT INTO student VALUES(%d, '%s', %d)", input_id, input_name, input_score);
    //调试数据库代码时 第一件事儿 先把要执行的sql语句打印出来
    // printf("yangfs sql:[%s]\n", sqlstr);
    //执行sql语句
    if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
        exit(-1);
    }
    printf("新学员信息插入成功..\n");
}

//修改学员信息的函数
void modify_student(sqlite3* my_db)
{
    //根据id修改学生的信息
    int modify_id = 0;
    char modify_name[256] = { 0 };
    int modify_score = 0;
    printf("请输入要修改的学员的id(INT):");
    scanf("%d", &modify_id);
    printf("请输入修改之后的学员的姓名name(CHAR):");
    scanf("%s", modify_name);
    printf("请输入修改之后的学员的成绩score(INT):");
    scanf("%d", &modify_score);

    //组装sql语句
    int ret = 0;
    char sqlstr[256] = { 0 };
    sprintf(sqlstr, "UPDATE student SET name='%s',score=%d WHERE id=%d", modify_name, modify_score, modify_id);
    printf("ghj sql:[%s]\n", sqlstr);

    //执行sql语句
    if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
        exit(-1);
    }
    printf("学员信息修改成功..\n");
}

//删除学员信息的函数
void delete_student(sqlite3* my_db)
{
    //根据id删除学生的信息
    int delete_id = 0;
    printf("请输入要删除的学员的id(INT):");
    scanf("%d", &delete_id);

    //组装sql语句
    int ret = 0;
    char sqlstr[256] = { 0 };
    sprintf(sqlstr, "DELETE student WHERE id=%d", delete_id);
    printf("ghj sql:[%s]\n", sqlstr);

    //执行sql语句
    if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
        printf("文件 %s 的第 %d 行出错, 错误码为[%d],错误信息为[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
        exit(-1);
    }
    printf("删除学员成功..\n");
}

int flag = 0; //控制打印表头的标志位 0需要打印  1不需要打印

// callback 回调函数
int callback(void* arg, int ncolumn, char** f_value, char** f_name)
{
    int i = 0;
    //先打印表头
    if (flag == 0) {
        for (i = 0; i < ncolumn; i++) {
            printf("%10s", f_name[i]);
        }
        printf("\n");
        flag = 1;
    }

    //再打印字段的值
    for (i = 0; i < ncolumn; i++) {
        printf("%10s", f_value[i]);
    }
    printf("\n");
    return 0; //必须写return 0   不然会报错query aborted
}

//查询学员信息的函数---基于callback实现
void search_student_1(sqlite3* my_db)
{
    printf("\n");
    //组装sql语句
    char sqlstr[256] = { 0 };
    int ret = 0;
    sprintf(sqlstr, "SELECT * FROM student");
    //执行sql语句
    if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, callback, NULL, NULL))) {
        printf("文件 %s 的第 %d 行出错, 错误码为[%d],错误信息为[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
        exit(-1);
    }
    flag = 0; //重置打印表头的标志位
    printf("学员信息查询成功..\n");
}

//查询学员信息的函数---基于sqlite3_get_table实现
void search_student_2(sqlite3 *my_db){
    printf("\n");
    char **result = NULL;
    int nrow = 0;
    int ncolumn = 0;
    //组装sql语句
    int ret = 0;
    char sqlstr[256] = {0};
    sprintf(sqlstr,"SELECT * FROM student");
    if(SQLITE_OK != (ret = sqlite3_get_table(my_db,sqlstr,&result,&nrow,&ncolumn,NULL))){
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",\
            __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
        exit(-1);
    }
    //先打印表头
    int i = 0;
    int j = 0;
    for(i = 0;i<ncolumn;i++){
        printf("%10s",result[i]);
    }
    printf("\n");

    //打印内容
    int index = i;
    for(i = 0;i<nrow;i++){
        printf("%10s",result[index++]);
    }
    printf("\n");

    //释放sqlite3_get_table产生的结果集
    sqlite3_free_table(result);

    printf("学员信息查询成功..\n");
}


//打印菜单的函数
void print_menu()
{
    printf("-----------------------------------------\n");
    printf("|  1.添加  2.修改  3.删除  4.查询  5.退出 |\n");
    printf("-----------------------------------------\n");
    printf("please input your choose : ");
}

int main()
{
    sqlite3* my_db = NULL;
    proc_init(&my_db);

    int choose = 0;

    while (1) {
        print_menu();
        scanf("%d", &choose);
        switch (choose) {
        case 1:
            insert_student(my_db);
            break;
        case 2:
            modify_student(my_db);
            break;
        case 3:
            delete_student(my_db);
            break;
        case 4:
            //可以用两种方式来实现数据库的查询
            //search_student_1(my_db);
            search_student_2(my_db);
            break;
        case 5:
            printf("期待您的再次使用...\n");
            break;
        }
        if (5 == choose) {
            break;
        }
    }

    //关闭数据库句柄
    sqlite3_close(my_db);

    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菜鸟选手_

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值