学生管理系统文件化以及SQL相关操作

1. SQL语句

关系型数据库 SQL语句都是通用的

用数据库的特点很明显,可以将数据保存在数据库文件中,可以永久保存,也可以使用数据库相关指令进行查看

1.建表语句(创建数据库文件时,不会创建数据表,需要我们手动创建)
	CREATE TABLE 表名(字段名1 字段的类型1, ...,字段名n 字段的类型n);
		字段类型:
			整型		INT 或者 INTEGER
			字符串		CHAR 或者 TEXT
	CREATE TABLE IF NOT EXIST student(id INT, name TEXT, score INTEGER);

2.向表中插入数据
	//注意,sql语句中出现的字符串要用 双引号 或者 单引号 引起来
	INSERT INTO student VALUES(1001, "张三", 98);
	//这种插入方式 要求必须从左到右给表的每个字段都赋值
	
	INSERT INTO student(id, name) VALUES(1002,"李四");
	//这种方式可以给指定的字段插入数据

3.查询表中的记录
	SELECT * FROM student; // * 表示查询所有字段
	SELECT id,score FROM student;//表示只查询 id 和 score 字段
	SELECT * FROM student WHERE score=96;//查询成绩是96的记录的所有字段
	SELECT * FROM student WHERE name="赵六";//查询名字是 赵六 的记录的所有字段
									       //字符串要加单引号或者双引号
	
	SELECT * FROM student WHERE name="赵六" AND score=90;
	SELECT * FROM student WHERE score=98 OR score=96;
	//可以使用AND或者OR连接多个条件 AND 并且  OR 或者
	
	//也可以将查询的结果排序
	SELECT * FROM student ORDER BY score DESC;
	//ORDER BY 表示根据那个字段排序
	//ASC 升序  DESC  降序   默认的是升序
	
	
4.修改表中的记录
	//将表中成绩为 1003 的记录score字段的值修改成60
	UPDATE student SET score=60 WHERE id=1003;
	//即使条件不成立 也能执行成功 只不过没有任何事情发生
	
	UPDATE student SET score=60,name="小红" WHERE id=1003;

5.删除表中的记录
	//在表中删除 name 为张三的记录
	DELETE FROM student WHERE name='张三';
	//即使条件不成立 也能执行成功 只不过没有任何事情发生
	
	//在表中删除 name 为张三的 或者 score为60 的记录
	DELETE FROM student WHERE name="赵六" OR score=60;

6.删除数据表
	DROP TABLE 表名;

7.添加一列
	ALTER TABLE student ADD COLUMN sex CHAR;
	
8.删除一列
	sqlite3 不允许直接删除一列
	1)先创建一张新表
	   create table temp as select id , name from student;
	2)删除原来的旧表
	   drop table student;
	3)对新表重命名
	   alter table temp rename to student;

9.数据库主键(设置的数据将会是唯一存在的,每张表只有一个)
	CREATE TABLE student(id INT PRIMARY KEY, name TEXT, score INTEGER);

2. 学生管理系统代码详情

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

#define DATABASE "stu_manage.db"

//进程初始化的函数
int proc_init(sqlite3** my_db)
{
    //打开数据文件
    int ret = 0;
    char* errmsg = NULL;
    if (SQLITE_OK != (ret = sqlite3_open(DATABASE, my_db))) {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
            __FILE__, __LINE__, ret, sqlite3_errmsg(*my_db));
        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(*my_db, 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)
{
    int modify_id = 0;
    char modify_name[32] = { 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);

    int ret = 0;
    char sqlstr[256] = { 0 };
    //组装sql语句
    sprintf(sqlstr, "UPDATE student SET name='%s',score=%d WHERE id=%d\n", modify_name, modify_score, modify_id);
    printf("modify: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)
{
    int delete_id = 0;

    printf("请输入要删除学员的id(INT):");
    scanf("%d", &delete_id);

    int ret = 0;
    char sqlstr[256] = { 0 };
    //组装sql语句
    sprintf(sqlstr, "DELETE FROM student WHERE id=%d\n", delete_id);
    //关于数据库的操作 出错首先检查sql语句的输出
    printf("delete:sql [%s]\n", sqlstr);
    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不需要打印

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

    //再打印字段的值
    for (i = 0; i < ncolum; i++) {
        printf("%10s", f_value[i]);
    }
    putchar(10);
    // 回调函数不加 return 会出现 错误 query aborted
    return 0;
}

//查询学员信息的函数---基于回调函数实现
void search_student_callback(sqlite3* my_db)
{
    //组装sql语句
    int ret = 0;
    char sqlstr[256] = { 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_sqlite3_get_table(sqlite3* my_db)
{
    puts("");
    char** result = NULL; //储存查询结果
    int nrow = 0; //行数
    int ncolumn = 0; //列数
    int ret = 0;
    char sqlstr[256] = { 0 };
    // 组装sql语句
    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]);
    }
    puts("");

    //再打印内容
    int index = i;
    for (i = 0; i < nrow; i++) {
        for (j = 0; j < ncolumn; j++) {
            printf("%10s", result[index++]);
        }
        puts("");
    }
    // 释放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_callback(my_db);
            search_student_sqlite3_get_table(my_db);
            break;
        case 5:
            printf("期待您的再次使用...\n");
            break;
        }
        if (5 == choose) {
            break;
        }
    }

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

    return 0;
}

程序测试图:

在这里插入图片描述

其中查询功能使用了两种方法:

1.callback回调函数–会根据sql语句查询到的结果 有几次结果就调用几次

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

    //再打印字段的值
    for (i = 0; i < ncolum; i++) {
        printf("%10s", f_value[i]);
    }
    putchar(10);
    // 回调函数不加 return 会出现 错误 query aborted
    return 0;
}

2.sqlite3_get_table 函数

这种方法需要调用sqlite3_free_table()释放结果集–

void search_student_sqlite3_get_table(sqlite3* my_db)
{
    puts("");
    char** result = NULL; //储存查询结果
    int nrow = 0; //行数
    int ncolumn = 0; //列数
    int ret = 0;
    char sqlstr[256] = { 0 };
    // 组装sql语句
    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]);
    }
    puts("");

    //再打印内容
    int index = i;
    for (i = 0; i < nrow; i++) {
        for (j = 0; j < ncolumn; j++) {
            printf("%10s", result[index++]);
        }
        puts("");
    }
    // 释放sqlite3_get_table产生的结果集
    sqlite3_free_table(result);

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值