一、数据库的操作
1.系统命令
系统命令是以 . 开头的,后面不能加分号
.help 打开帮助
.quit 退出数据库
.exit 退出数据库
.open 打开数据库文件
.tables 查看数据库中有哪些表
.schema 显示建表语句(表的结构)
2.关系型数据库结构
3.sql语句
sql语句是关系型数据库通用的,会操作sqlite了,其他的数据库,如mysql也是一样的
sql语句的关键字不区分大小写,但是一般关键字都写成大写
sql语句不能以 ” . “开头 且后面要加分号” ; “
① 创建一张表(打开数据库文件是不会默认创建表的,需要自己创建)
CREATE TABLE 表名(字段1 字段1的类型,… ,字段n 字段n的类型);
字段类型:
整数 :INT 或者 INTEGER
字符串:CHAR 或者 TEXT
例如: CREATE TABLE student(id INT, name TEXT, score INTEGER);
② 向表中添加记录
INSERT INTO 表名 VALUES(各个字段的值用逗号分隔); //这种方式需要给字段赋值,不能空
INSERT INTO 表名(字段名用逗号分隔) VALUES(各个字段的值用逗号分隔); //可以只插入几个字段
例如:INSERT INTO student VALUES(1001,”张三”,98);
INSERT INTO student(id,name) values(1002, ‘李四’);
③ 查询表中的记录
SELECT * FROM student; // * 表示要查询所有的字段
SELECT * FROM student; // * 表示要查询所有的字段
SELECT * FROM student WHERE score=98; //在表中查询成绩为98的所有记录的所有字段
SELECT * FROM student WHERE name=”王五”; //注意sql语句中 字符串要加 单引号或双引号
SELECT * FROM student WHERE score=98 OR name=’李四’; //成绩98 或者 名字叫李四
SELECT * FROM student WHERE score=98 AND name=’王五’; //成绩98 并且 名字叫王五
SELECT * FROM student ORDER BY score ASC; //ORDER BY 表示根据那个字段排序 ASC 升序 DESC 降序
④ 修改记录内容
UPDATE student SET score=96 WHERE id=1002; //将 student 表中 id=1003 的项全删除
⑤ 删除记录
DELETE FROM student WHERE id=1003; //将 student 表中 id=1003 的项全删除
⑥ 删除表
DROP TABLE 表名;
⑦添加一列 (了解)
ALTER TABLE student ADD COLUMN age INT;
⑧删除一列 (了解)
sqlite3 不允许直接删除一列
1)先根据原表的数据创建一张新表
CREATE TABLE temp1 AS SELECT id,name FROM student;
2)删除原来的旧表
DROP TABLE student;
3)对新表重命名
ALTER TABLE temp1 RENAME TO student;
⑨ 数据库主键(既设置的数据将会是唯一存在的)—- 很重要
CREATE TABLE usr(name TEXT PRIMARY KEY , passwd TEXT);
4.sqlite数据库常用的API接口
使用sqlite3的函数头文件是:sqlite3.h
编译是要链接sqlite3的库: -lsqlite3
① 打开一个数据库
int sqlite3_open(const char filename, / Database filename (UTF-8) /
sqlite3 ppDb / OUT: SQLite db handle */ );
参数:
@filename:数据库名字
@ppDb:操作数据库的指针,句柄。
返回值: 成功返回SQLITE_OK,失败返回error_code
② 获取错误信息描述
const char sqlite3_errmsg(sqlite3 db);
参数:sqlite3的句柄
返回值: 错误信息(最后一次出错的信息)
③ 执行sql语句的函数
int sqlite3_exec( sqlite3 db, const char sql, int (callback)(void,int,char,char), void * arg, char **errmsg );
功能:执行一条sql语句
参数:
@db:数据库的句柄指针
@sql:将要被执行sql语句
@callback:回调函数,只有在查询语句时,才给回调函数传参
@arg:为callback 传参的
@errmsg:错误信息的地址,如果使用了,需要用 sqlite3_free() 释放空间
返回值: 成功返回SQLITE_OK,失败返回errcode 错误码
注:sqlite3_exec的回调函数:
int (callback)(void arg ,int ncolumn ,char f_value,char f_name)
功能:得到查询结果,注意:每查到一条记录该函数就会被调用一次
参数:
@arg:为回调函数传递参数使用的
@ncolumn:记录中包含的字段的数目
@f_value:包含每个字段值的指针数组
@f_name:包含每个字段名称的指针数组
返回值: 成功返回0,失败返回非0
④ 查询结果的函数
char p = NULL;
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(result);
⑥ 关闭sqlite数据库句柄
sqlite3_close(db);
二、使用数据库实现学生管理系统
#include <stdio.h>
#include <sqlite3.h>//sqlite3数据库函数的头文件
#include <stdlib.h>
int flag = 0;//控制打印表头的标志位 0 要打印 1 不打印
void print_menu(){
printf("*******************************************\n");
printf("** 1.添加 2.修改 3.查询 4.删除 5.退出 **\n");
printf("*******************************************\n");
printf("input your choose:");
}
//程序初始化的函数
sqlite3 *proc_init(){
sqlite3 *my_db = NULL;
char *errmsg = NULL;
//文件存在直接打开,文件不存在则新建并打开
int ret = sqlite3_open("hqyj.db", &my_db);
if(SQLITE_OK != ret){
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
//建表 IF NOT EXISTS 表示
//不存在就创建 如果存在就直接使用 而不是报错
char buff[128] = {0};
sprintf(buff, "%s", "CREATE TABLE IF NOT EXISTS student(id INT PRIMARY KEY, name TEXT, score INT)");
if(SQLITE_OK != (ret = sqlite3_exec(my_db, buff, NULL, NULL, &errmsg))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, errmsg);
exit(-1);
}
//释放内存
sqlite3_free(errmsg);
return my_db;
}
//根据学号删除学员
void delete_student(sqlite3 *my_db){
int ret = 0;
int id = 0;
printf("请输入要删除的学员的 id(INT):");
scanf("%d", &id);
//组装sql语句,可以不用加分号
char buff[128] = {0};
sprintf(buff, "DELETE FROM student WHERE id=%d", id);
//执行sql语句
if(SQLITE_OK != (ret = sqlite3_exec(my_db, buff, NULL, NULL, NULL))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
//exit(-1);
printf("删除失败\n");
return;
}
printf("删除成功\n");
}
//根据学号修改学员信息
void modify_student(sqlite3 *my_db){
int ret = 0;
int id = 0;
char name[32] = {0};
int score = 0;
printf("请输入要修改的学员的 id(INT) 以及新的name(TEXT) score(INT):");
scanf("%d%s%d", &id, name, &score);
//组装sql语句,可以不用加分号
char buff[128] = {0};
sprintf(buff, "UPDATE student SET name='%s',score=%d WHERE id=%d", name, score, id);
//执行sql语句
//即使where后面的条件不存在 语句也能执行成功 只是相当于没做事儿
if(SQLITE_OK != (ret = sqlite3_exec(my_db, buff, NULL, NULL, NULL))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
//exit(-1);
printf("修改失败\n");
return;
}
printf("修改成功\n");
}
//插入学员
void insert_student(sqlite3 *my_db){
int ret = 0;
int id = 0;
char name[32] = {0};
int score = 0;
printf("请输入要插入的学员的 id(INT) name(TEXT) score(INT):");
scanf("%d%s%d", &id, name, &score);
//组装sql语句,可以不用加分号
char buff[128] = {0};
sprintf(buff, "INSERT INTO student VALUES(%d,'%s',%d)", id, name, score);
//执行sql语句
//即使where后面的条件不存在 语句也能执行成功 只是相当于没做事儿
if(SQLITE_OK != (ret = sqlite3_exec(my_db, buff, NULL, NULL, NULL))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
//exit(-1);
printf("插入失败\n");
return;
}
printf("插入成功\n");
}
//callback回调函数
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;
}
//再打印记录的值
for(i = 0; i < ncolumn; i++){
printf("%10s", f_value[i]);
}
printf("\n");
return 0;//必须要写返回值 否则报错 query aborted
}
//查询所有学员信息----使用callback实现
void select_student1(sqlite3 *my_db){
int ret = 0;
//组装sql语句,可以不用加分号
char buff[128] = {0};
sprintf(buff, "SELECT * FROM student");
//执行sql语句
if(SQLITE_OK != (ret = sqlite3_exec(my_db, buff, callback, NULL, NULL))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
//exit(-1);
printf("查询失败\n");
return;
}
flag = 0;//重置标志位
printf("查询成功\n");
}
//查询所有学员信息----使用sqlite3_get_table 实现
void select_student2(sqlite3 *my_db){
int ret = 0;
char **result = NULL;
int nrows = 0;
int ncolumns = 0;
//组装sql语句,可以不用加分号
char buff[128] = {0};
sprintf(buff, "SELECT * FROM student");
//执行sql语句
if(SQLITE_OK != (ret = sqlite3_get_table(my_db, buff, &result, &nrows, &ncolumns, NULL))){//最后一个参数如果使用了需要自己手动释放
printf("%s(%d) : errcode:[%d] errmsg:[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
//exit(-1);
printf("查询失败\n");
return;
}
//输出结果
//先输出表头
int i = 0;
int j = 0;
for(i = 0; i < ncolumns; i++){
printf("%10s", result[i]);
}
int index = i;
printf("\n");
//输出各条记录的各个字段的值
for(i = 0; i < nrows; i++){//i控制查到的记录数
for(j = 0; j < ncolumns; j++){//j控制的每条记录的字段数
printf("%10s", result[index++]);
}
printf("\n");
}
//防止内存泄漏,使用完结果集后要手动释放空间
sqlite3_free_table(result);
printf("查询成功\n");
}
int main(){
sqlite3 *my_db = proc_init();
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:
//select_student1(my_db);
select_student2(my_db);
break;
case 4:
delete_student(my_db);
break;
case 5:
break;
default:
printf("输入错误,请重新输入(1-5)\n");
break;
}
if(5 == choose){
break;
}
}
//关闭sqlite3 句柄
sqlite3_close(my_db);
return 0;
}</stdlib.h></sqlite3.h></stdio.h>
注:代码中的回调函数可能不理解的点:
Original: https://blog.csdn.net/zhangts318/article/details/124534712
Author: zhangts318
Title: sqlite3数据库实现学生管理系统
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815354/
转载文章受原作者版权保护。转载请注明原作者出处!