复习
数据库
/
//数据存储三种方式
1 直接地址存储 (早期的51单片机 stm32 ....)
2 文件(数据量不大,数据规律性不强,而且需要方便读取,那就放到文件中)
存储用户名,密码, ip地址 等等一些配置信息
3 数据库(学生管理系统、库存系统)
大型数据库(银行、电信)
oracle (用的最多的 电信 社保 ....)
甲骨文
sybase (有一些老系统 银行)
中型数据库
mysql (甲骨文公司)
优点: 开源
哪些系统用mysql (腾讯 阿里 百度 googlee)
sql server (微软公司)
小型数据库
sqlite (用在嵌入式设备、手机、导航)
优点: 数据库小(安装后 就占用 几十k)
很多系统默认带sqlite数据库(QT 自带sqlite数据库)
4 云存储 (阿里云 腾讯云 华为云)
sqlite(平台ubuntu)
安装数据库
1 用下载好的安装包安装
libsqlite3-0_3.7.2-1ubuntu0.1_i386.deb (.deb的安装包可以用dpkg -i 来进行安装)
sudo dpkg -i libsqlite3-0_3.7.2-1ubuntu0.1_i386_1.deb //dpkg -i 安装文件
sudo dpkg -i libsqlite3-dev_3.7.2-1ubuntu0.1_i386_2.deb
sudo dpkg -i sqlite3_3.7.2-1ubuntu0.1_i386_3.deb
linux@ubuntu:~$ sqlite3 --version (--version 查看版本号)
3.7.2
2 打开数据库
sqlite3 my.db (如果my.db 存在就打开,不存在就新建)
数据库 一般 扩展名是.db
输入 .开头的命令(非sql语句命令)
.help
.quit
.tables
还有一种命令不是以.开头的,这种叫sql语句,sql语句以 ; 结束
总结:
sqlite3 以.开头是 sqlite3命令
不是以.开头 是 sql语句,一定以;结束
//
数据库中有哪些概念
数据库
将所有的数据,各种类型,描述各种事物的数据放到一起,
如:my.db文件,就是一个数据库文件
数据表
描述某一个事物的基本信息的表
图书管理系统 (book.db)
学生信息表 (stu_info)
编号 姓名 性别 年龄 班级 爱好
图书信息表 (book_info)
图书编号 书名 出版社 作者 分类
借阅表 (lend_info)
记录
表里面的一条信息
字段
列名
/下面的这些语句是标准sql语句,各个数据库都支持///
如何创建数据表
create table stu_info (number varchar(20), name varchar(50), age integer, sex varchar(10));
varchar 可变长的字符串
(20) 最大长度20个字符
integer 整型
一个汉字占用2个字符
注意,上面命令可以在终端中执行,执行时 一定 不要加. , 命令结束要加;
.tables 查看系统有多少数据表
drop table stu_info; //删除表
插入记录
insert into stu_info values ('1001', 'zhangsan', 25, 'nan'); //所有字段全都填入值
insert into stu_info values ('1003', 'lisi', 24, 'nan'); //所有字段全都填入值
insert into stu_info values ('1004', 'xiaoliu', 27, 'nan'); //所有字段全都填入值
//只给某些字段添加值
insert into stu_info (number, age) values ('1002', 26);
查询记录
select * from stu_info; //select 选择 * 所有字段
.header on 显示字段名
.mode column 列对齐
怎么查询一条指定的记录
查询名字是李四的记录
select * from stu_info where name = 'lisi';
练习
1 创建学生成绩表(字段如下)
学生编号 数学 语文 英语
create table score_info (number varchar(20), math integer, ch integer, en integer);
2 向学生成绩中添加三条记录
1001 100 90 80
1002 80 90 80
1003 90 90 80
insert into score_info values ('1001', 100, 90, 80);
insert into score_info values ('1002', 80, 90, 80);
insert into score_info values ('1003', 90, 90, 80);
3 查询出编号1003的记录
select * from score_info where number = '1003';
其他各种查询
1 查询年龄是25的记录
select * from stu_info where age = 25;
2 查询年龄 > 25的记录
select * from stu_info where age > 25;
3 查询记录 只想看编号、姓名字段
select number, name from stu_info where age = 25;
4 如果想按顺序输出所有记录,按年龄排序
select * from stu_info order by age; //默认情况是升序排列(asc)
select * from stu_info order by age desc; //降序排列
5 模糊查询(假设有一个人名我记不住了,但能记住名字中的一个字, 就可以用模糊查询)
查询名字当中带li字符的人
select * from stu_info where name like '%li%';
6 统计记录条数
select count(*) from stu_info;
select count(*) from stu_info where age > 25;
7 统计所有人的年龄总和
select sum(age) from stu_info;
8 统计所有人的年龄平均值
select avg(age) from stu_info;
///
9 多条件查询
想查询年龄大于 25, 编号 > 1001 的学生信息
select * from stu_info where age > 25 and number > 1001;
select * from stu_info where age > 25 and number > 1001 and name like '%l%';
删除记录
//delete from stu_info; //删除所有记录
delete from stu_info where name = 'lisi';
修改记录
1002 , name改成wangwu
update stu_info set name = 'wangwu' where number = '1002';
update stu_info set name = 'wangwu', sex = 'nan' where number = '1002';
通过脚本执行sql语句
将所有的sql语句,写到一个文件中,然后执行这个文件,就把所有语句都执行了
写一个文件 create_score_info.sql
##############################################################
drop table if exists score_info; #如果score_info存在就删除
create table score_info(number varchar, math integer, ch integer, en integer);
insert into score_info values('1001', 95, 87, 62);
insert into score_info values('1002', 90, 88, 65);
insert into score_info values('1003', 92, 86, 66);
insert into score_info values('1004', 98, 77, 72);
#############################################################
执行文件 ( < 输入重定向 重定向为 脚本 )
sqlite3 my.db < create_score_info.sql;
多表联合(查询数学成绩 > 90的所有学生的基本信息和成绩)
学生基本信息表
number name age sex
成绩表
nubmer math ch en
两个表number相同
select stu_info.*, score_info.math, socre_info.ch from stu_info, score_info
where score_info.math > 90 and stu_info.number = score_info.number;
练习:
图书管理系统(book.db)
1 创建图书基本信息数据表 图书编号 图书名称 出版社 作者 出版日期
2 创建办理借阅卡的学生基础表 学生编号 学生姓名 所在系 所在班
3 创建学生借阅表 学生编号 图书编号 借阅日期 借阅时间(天数) 是否归还
4 添加记录并查询
查询指定出版社的图书信息
查询指定作者的图书信息
查询某个编号的学生基本信息
查询已借出图书的图书名称
修改某个编号的图书的基本信息
删除借阅时间大于2天的借阅信息
FILE *fp = fopen("hello.c", "r"); //通过返回值得到指向文件的指针
DIR *dp = opendir();
//
用c语言操作数据库(打开数据库,执行sql语句)
1 打开数据库
sqlite3_open(char *path, sqlite3 **db);
功能: 打开数据库, 如果不存在就新建
参数:
path 数据库名("my.db")
db 二级指针(是一个出参,打开成功会传出一个指针,指向这个数据库)
返回值:
SQLITE_OK 成功
其他: 失败
sqlite3 *db;
sqlite3_open("my.db", &db); //**db *db db &db *(&db)
执行前,db是野指针,执行后,指向数据库
#include
#include
int main()
{
sqlite3 *p; //如果打开成功,将指向数据库的指针赋值给p
if(sqlite3_open("my.db", &p) == 0) //如果数据库不存在,就创建
{
printf("database open success\n");
}
}
编译-l sqlite3 (-l 表示加载第三方库文件 sqlite3库文件名 全程 libsqlite3.so)
gcc -o test test.c -lsqlite3
2 执行数据库操作的sql语句 (insert into create table update delete)
int sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void *para, char **errmsg);
功能: 用来执行sql 语句
参数 db , sqlite_open 传出的值 (指向数据库的指针)
sql, sql语句 ( "insert into stu_info values('1001', 'xiaoli', 25, 'nan')" )
callback 通常为NULL
para 通常为NULL
errmsg: 可以为NULL, 二级指针,传进一个一级指针地址,此指针指向 sql执行出错的错误字符串
#include
#include
int main()
{
sqlite3 *p;
if(sqlite3_open("my.db", &p) == 0) //如果数据库不存在,就创建
{
sqlite3_exec(p, "delete from stu_info where name = 'zhangsan'", NULL, NULL, NULL);
printf("database open success\n");
}
}
调试排错过程:
1) 用printf 打印sql语句
2) 用errmsg 找到错误提示
#include
#include
int main()
{
sqlite3 *p;
char *err;
if(sqlite3_open("my.db", &p) == 0) //如果数据库不存在,就创建
{
char sql[] = "delete frm stu_info where name = 'xiaoli'";
if(sqlite3_exec(p, sql, NULL, NULL, &err)!= 0)
{
printf("error:%s\n", err);
printf("%s\n", sql);
}
}
}
linux@ubuntu:~$ ./a.out
error:near "frm": syntax error
练习:
1 从键盘输入编号,姓名,年龄,性别,插入到stu_info中
提示: sprintf
char name[50];
scanf("%s", name);
sprintf(sql, "inser .... '%s'", name);
#include
#include
int main()
{
sqlite3 *p;
if(sqlite3_open("my.db", &p) == 0) //如果数据库不存在,就创建
{
char sql[100] = { 0 }; //保存sql语句
char *q;
char name[20]; //存输入名字
char number[20];
int age;
char sex[10];
scanf("%s%s%d%s", name, number, &age, sex);
sprintf(sql, "insert into stu_info values('%s', '%s', %d, '%s')", name, number, age, sex);
int ret = sqlite3_exec(p, sql, NULL, NULL,&q);
if(ret != 0)
{
printf("%s\n", sql);
printf(" %d : %s\n", ret, q);
}
}
}
假设所有字段都是 字符串
"1001" "xiaoli" "nan"
"1002" "xiaowang" "nan"
"1003" "xiaozhang" "nv"
"1004" "xiaozhao" "nv"
char *p[12] = {"1001", "xiaoli", "nan", "1002", "xiaowang", "nan" ....};
列: 3
行: 4
#include
int main()
{
char *p[] = {"1001", "xiaoli", "nan","1002", "xiaowang", "nan","1003", "xiaozhang", "nv",
"1004", "xiaozhao", "nv"};
char **q = p;
int i, j;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 3; j++)
{
printf("%s ", *q); //printf("%s", p[i * 3 + j]);
q++;
}
printf("\n");
}
}
查询语句
int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int*nrow, int *ncolumn, char **errmsg);
功能:执行SQL操作
db:数据库句柄, open的第二个参数
sql:SQL语句, (select * from stu_info)
resultp:用来指向sql执行结果的指针 (跟errmsg类似)
nrow:满足条件的记录的数目, 包括字段名,相当于行数
ncolumn:每条记录包含的字段数目,相当于列数
errmsg:错误信息指针的地址, 如果语句执行出错,那么errmsg中是错误信息
返回值:成功返回0,失败返回错误码
#include
#include
#include
int main()
{
sqlite3 *db;
char *errmsg, **resultp;
int nrow, ncolumn, i, j, index;
if(sqlite3_open("my.db", &db) == 0)
{
if(sqlite3_get_table(db, "select * from stu_info", &resultp, &nrow, &ncolumn, &errmsg) != 0)
{
printf("error : %s\n", errmsg);
exit(-1);
}
else
{
index = ncolumn; // 第一条记录的第一个字段的下标 // 4
for(i = 0;i < ncolumn; i++)
printf("%10s", resultp[i]); //输出字段名
printf("\n");
for (i=0; i
for (j=0; j
printf("%10s", resultp[index++]);
}
printf("\n");
}
}
}
}
"number" "name" "age" "sex" "1001" "xiaoli" "25" "nan" "1002" "xiaowang" "26" "nan"
练习:
1 循环5次从键盘输入编号,姓名,年龄,性别,插入到stu_info中
2 查询年龄 > 25 的打印出来
#include
#include
#include
int main()
{
sqlite3 *db;
char *errmsg,**resultp;
int nrow, ncolumn, i, j, index;
if(sqlite3_open("my.db", &db) == 0) //如果数据库不存在,就创建
{
char sql[100] = { 0 };
char name[20];
char number[20];
int age;
char sex[10];
for(i = 0; i < 5; i++)
{
scanf("%s%s%d%s", name, number, &age, sex);
sprintf(sql, "insert into stu_info values('%s', '%s', %d, '%s')", number, name, age, sex);
int ret = sqlite3_exec(db, sql, NULL, NULL,&errmsg);
if(ret != 0)
{
printf(" %d : %s\n", ret, errmsg);
}
}
printf("please input age:\n");
scanf("%d", &age);
sprintf(sql, "select * from stu_info where age > %d", age);
if(sqlite3_get_table(db, sql, &resultp, &nrow, &ncolumn, &errmsg) != 0)
{
printf("error : %s\n", errmsg);
exit(-1);
}
else
{
index = ncolumn; // 第一条记录的第一个字段的下标 // 4
for(i = 0;i < ncolumn; i++)
printf("%-10s", resultp[i]);
printf("\n");
for (i=0; i
for (j=0; j
printf("%-10s", resultp[index++]);
}
printf("\n");
}
}
}
}