华清远见25072班网络编程学习day6
重点内容:
数据库基本概念:
数据(Data):能够输入计算机并能被计算机程序识别和处理的信息集合数据 (Database)
数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合
重要概念:
记录:能够描述一条数据的完整信息称为一个记录(就是数据结构中的数据元素)
字段:描述数据中的最小不可再分割的单元(就是数据结构中的数据项)
SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
零配置 一 无需安装和管理配置;
储存在单一磁盘文件中的一个完整的数据库;
数据库文件可以在不同字节顺序的机器间自由共享;
支持数据库大小至2TB;
足够小,全部源码大致3万行c代码,250KB;
比目前流行的大多数数据库对数据的操作要快;
sqlite3命令语句:
1. sqlite数据库创建
1.sqlite3 xxx.db
2.sqlite3-->.open xxx.db
2. 系统命令,也称为点命令
系统命令,需要以 . 开头,不需要以 ; 结尾
.quit 退出数据库
.exit 退出数据库
.help 显示帮助信息,获取所有系统命令;
.table 查看当前数据库下的所有表格;
.schema 查看表的结构
3. sql语句
1)创建表格
create table 表名 (字段名 数据类型, 字段名 数据类型);
create table if not exists 表名 (字段名 数据类型, 字段名 数据类型);
2)删除表格
drop table 表名;
3)插入记录
insert into 表名 values (数据1, 数据2, 数据3);-->全字段插入
insert into 表名 (字段名1, 字段名2) values (数据1, 数据2);-->部分字段插入
4)查看记录
.header on 打开表头
.mode column 对齐
select * from 表名;-->查看所有记录
select * from 表名 where 限制条件;-->查看某几行
select 字段1, 字段2 from 表名;-->查看某几列
select 字段1, 字段2 from 表名 where 限制条件;-->查看某几列
5)修改记录
update 表名 set 字段=数值 where 限制条件;
6)删除记录
delete from 表名 where 限制条件;
7)主键(primary key)
create table 表名(字段名 数据类型 primary key, 字段名 数据类型 );
primary key主键:唯一标识表格中的每一条记录;
8)拷贝
从a中拷贝所有数据到b中: create table b as select * from a;
从a中拷贝指定字段到b中: create table b as select 字段,字段,字段 from a;
9)增加列
alter table 表名 add column 字段名 数据类型;
10)修改表名
alter table 旧表名 rename to 新表名;
11)修改字段名(列名)
不支持直接修改列名
1.将表重新命名(a改成b) alter table stuinfo rename to stu;
2.新建修改名字后的表(新建一个a) create table stuinfo (name char, age1 int, sex char, score int);
3.从旧表b中取出数据,插入到新表a中; insert into stuinfo select * from stu;
12)删除列
不支持直接删除列;
1.创建一个新表b,并复制旧表a需要保留的字段信息; create table stu as select name, age1, sex from stuinfo;
2.删除旧表a; drop table stuinfo;
3.修改新表b的名字a; alter table stu rename to stuinfo;
sqlite3 API:
1. sqlite3的C - APIs
1)sqlite3_open
int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ );
功能:打开一个数据库,如果数据库不存在,则创建一个数据库并打开
参数1:要打开的数据库的名字,是一个字符串
参数2:数据库操作句柄,是一个二级指针,需要我们传入一级指针的地址,如果打开数据库成功,则数据库指针由该参数返回
返回值:成功返回SQLITE_OK,失败返回一个错误码(非linux的错误码),可以使用sqlite3_errmsg来获取错误信息,由sqlite3_errcode返回错误码值
注意:无论打开数据库是否成功,在不使用数据库时都应该使用sqlite3_close将其关闭
2)sqlite3_close
int sqlite3_close(sqlite3*);
功能:关闭数据库,断开句柄所拥有的资源
参数:数据库指针
返回值:成功返回SQLITE_OK,失败返回其他错误码
3)sqlite3_errmsg
const char *sqlite3_errmsg(sqlite3*);
功能:通过出错的句柄返回错误信息
参数:出错的句柄
返回值:对应的错误信息,是一个字符串
4)sqlite3_errcode
int sqlite3_errcode(sqlite3 *db)
功能:通过错误句柄返回错误码
参数:错误句柄
返回值:错误码
5)sqlite3_exec
int sqlite3_exec( sqlite3* db, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *arg, /* 1st argument to callback */ char **errmsg /* Error msg written here */ );
功能:调用该函数,执行sql语句
参数1:已经被打开的数据库句柄
参数2:要执行的sql语句
参数3:回调函数,主要用于数据库查找时,处理查找的结果集的函数,如果不需要处理sql语句的结果,则填NULL即可
参数4:参数3的第一个参数
参数5:错误信息 返回值:成功返回SQLITE_OK,失败返回其他错误码
6)回调函数
int callback(void* arg,int cols, char** msgtext, char** msgheader)
功能:回调函数,对于sql语句执行后的每一个记录行执行该回调函数
参数1:exec传递进来的参数
参数2:当前要处理的结果行的总列数
参数3:当前结果行信息的起始地址
参数4:当前结果行表头的起始地址
返回值:成功返回0,失败返回-1;
7)sqlite3_get_table
onst char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ );
功能:通过执行sql语句,得到结果集中的内容
参数1:数据库句柄
参数2:要执行的sql语句
参数3:查询结果的起始地址,需要定义一个二级指针变量,将地址进行传递
参数4: 查询结果的行数(不包括表头)
参数5:查询结果的列数
参数6:错误信息
返回值:成功返回SQLITE_OK,失败返回非0的错误码
8)sqltie3_free_table
void sqlite3_free_table(char **result);
功能:释放表的空间
参数:通过sql语句查询的结果
作业:
1> 实现一个XXX管理系统
程序源码:
#include <25072head.h>
//定义添加学生信息函数
int do_add(sqlite3 *ppDb)
{
int add_id; //要添加的id号
char add_name[20]; //要添加的姓名
double add_score; //要添加的成绩printf("请输入要添加学生的学号:");
scanf("%d", &add_id);
printf("请输入要添加学生的姓名:");
scanf("%s", add_name);
printf("请输入要添加学生的成绩:");
scanf("%lf", &add_score);
getchar();
//准备sql语句
char sql[128] = "";
sprintf(sql ,"insert into stuinfo values(%d, \"%s\",%.2lf);", \
add_id,add_name,add_score);
//执行sql语句
char *errmsg = NULL;
if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("添加失败:%s\n", errmsg);
sqlite3_free(errmsg);
errmsg = NULL;
return -1;
}
if(sqlite3_changes(ppDb) != 0)
{
printf("添加成功\n");
}
return 0;
}
int do_delete(sqlite3 *ppDb)
{
int delete_id; //要删除的id号
printf("请输入要删除学生的学号");
scanf("%d",&delete_id);
getchar();
//准备sql语句
char sql[128]="";
sprintf(sql,"delete from stuinfo where id=%d;",delete_id);
//执行sql语句
char *errmsg=NULL;
if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("删除失败:%s\n", errmsg);
sqlite3_free(errmsg);
errmsg = NULL;
return -1;
}
if(sqlite3_changes(ppDb) != 0)
{
printf("删除成功\n");
}
return 0;
}
int do_update(sqlite3 *ppDb)
{
int update_id; //要修改的id号
char update_name[20]; //要修改的姓名
double update_score; //要修改的成绩
printf("请输入要修改学生的学号:");
scanf("%d", &update_id);
printf("请输入修改后的学生姓名:");
scanf("%s", update_name);
printf("请输入修改后的学生成绩:");
scanf("%lf", &update_score);
getchar();
//准备sql语句
char sql[128]="";
sprintf(sql,"update stuinfo set name=\"%s\",score=%.2lf where id=%d;",update_name,update_score,update_id);
//执行sql语句
char *errmsg=NULL;
if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("修改失败:%s\n", errmsg);
sqlite3_free(errmsg);
errmsg = NULL;
return -1;
}
if(sqlite3_changes(ppDb) != 0)
{
printf("修改成功\n");
}
return 0;
}
//自定义查询函数的回调函数
int callback(void *arg, int cols, char **msgtext, char **msgheader)
{
if( *(int *)arg ==0)
{
//先输出表头
for(int i=0; i<cols; i++)
{
printf("%s\t", msgheader[i]);
}
printf("\n");
*(int *)arg = 1;
}
//输出内容
for(int i=0; i<cols; i++)
{
printf("%s\t", msgtext[i]);
}
printf("\n");
return 0;
}
//定义查找函数
int do_search(sqlite3 *ppDb)
{
//1.准备sql语句
char *sql = "select * from stuinfo;";
//2.执行sql语句
char *errmsg = NULL;
int flag = 0;
if(sqlite3_exec(ppDb, sql, callback, &flag, &errmsg) != SQLITE_OK)
{
printf("查询失败:%s\n", errmsg);
sqlite3_free(errmsg);
errmsg = NULL;
return -1;
}
printf("查询成功\n");
return 0;
}
int main(int argc, const char *argv[])
{
//1,打开数据库并返回一个操作该数据库的句柄
sqlite3 * ppDb=NULL;
if(sqlite3_open("./my.db",&ppDb)!=SQLITE_OK)
{
printf("my.db open error errcode=%d,errmsg=%s\n",\
sqlite3_errcode(ppDb),sqlite3_errmsg(ppDb));
return -1;
}
//程序执行至此,后期可以使用ppDb指针,进行数据库操作了
//创建一个学生信息表
char *sql="create table if not exists stuinfo(id int primary key,\
name text not NULL,score double);";
//定义指针接收执行sql语句后的错误信息
char *errmsg=NULL;
if(sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
printf("创建数据表失败:%s\n",errmsg);
sqlite3_free(errmsg);
errmsg=NULL;
return -1;
}
printf("学生信息表创建成功!\n");
int menu = -1;
while(1)
{
system("clear"); //执行系统终端指令
printf("\t\t==============XXX学生管理系统=============\n");
printf("\t\t==============1、增=======================\n");
printf("\t\t==============2、删=======================\n");
printf("\t\t==============3、改=======================\n");
printf("\t\t==============4、查=======================\n");
printf("\t\t==============0、退出=======================\n");
printf("请输入功能:");
scanf("%d", &menu);
getchar();
//多分支选择
switch(menu)
{
case 1:
{
do_add(ppDb);
}
break;case 2:
{
do_delete(ppDb);
}
break;case 3:
{
do_update(ppDb);
}
break;
case 4:
{
do_search(ppDb);
}
break;
case 0: exit(EXIT_SUCCESS);
default:printf("输入有错,请重新输入\n");
}
printf("按任意键后,按回车清屏\n");
while(getchar() != '\n');
}
//关闭数据库
sqlite3_close(ppDb);
return 0;
}
2> 思维导图
3> 牛客网