小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
数据库
官网:
1 在ubuntu中安装sqlite数据库
离线安装:
将.deb包拖入ubuntu中,并执行sudo dpkg -i *.deb即可
在线安装:
sudo apt-get install sqlite3 libsqlite3-dev
安装完之后进行测试:
终端输入sqlite3,如果能够进入数据库说明安装成功
2 创建或者打开指定数据库
方法1:在终端数据sqlite3的后面加数据库的名字,数据库名一般以.db作为后缀名
方法2:终端输入sqlite3,然后进入软件之后在输入.open 跟数据库名
3 数据库的操作
3.1 数据库的命令分类
系统命令:是以.开头的命令,主要用于对当前数据库操作
注意:系统命令后面不能加;
普通命令:是以;结尾的命令,主要对数据库中的表进行操作
注意:普通命令前面不能加.
3.2 常用的系统命令
.help 查看帮助信息,列出所有的系统命令 .exit 退出数据库 .quit 退出数据库 .databases 查看当前数据库的信息 .tables 列出当前数据库中所有表的表名 .schema 列出当前数据库中所有表的结构
3.3数据库的结构
数据库类似excl表格,当创建好一个数据库之后,不会自动给你创建表的,需要自己创建
数据库中表的结构:
3.4 数据库中常用sql语句
【1】sqlite常用命令
1-- 安装数据库:
sudo dpkg -i *.deb
2-- 创建数据库
sqlite3 stu.db
3-- 系统命令
- 系统命令 以 "."开头(系统命令后面不能加;)
- 普通命令 ,以";"结束 (普通命令前面不能加.)
.schema 查看表的结构
.quit 退出数据库
.exit 退出数据库
.help 查看帮助信息
.databases 查看数据库
.tables 显示数据库中所有的表的表名
4-- 普通命令
1-- 创建一张表
create table 表名(字段名称1 字段类型,字段名称2 字段类型, ....);
例如:create table stu(id int, name char, sex char , score int);
2-- 向表中插入一条记录
insert into 表名 values (字段值1,字段值2,...);
insert into stu values(1001, 'zhangsan', 'm', 89);
insert into stu (id, name, sex,score) values(1002, 'lisi', 'm', 99);
3-- 查询记录
select * from stu; // 查找所有的记录
select * from stu where id=1001; // 查找符号条件的记录
select * from stu where id=1001 and name='zhangsan'; // 字符串需要加引号
select * from stu where name='zhangsan' or score=92;
- ==.headers on 显示列表名==
- ==.mode column 按照列显示内容==
4-- 删除记录
delete from stu where id=1004;
5-- 更新记录
update stu set score=98 where id=1003;
6-- 删除一张表
drop table stu;
7-- 添加一列
alter table stu add column score int;
8-- 删除一列
sqlite3 不允许直接删除一列
- 1)先创建一张新表
create table stu1 as select id , name from stu;
- 2)删除原来的旧表
drop table stu;
- 3)对新表重命名
alter table stu1 rename to stu;
9-- 数据库主键(既设置的数据将会是唯一存在的)
create table usr(name text primary key , passwd text);
比如说注册用户的时候,可以把用户名设置成主键,这样用对应某一个用户名的密码等信息就成了唯一的。
4 sqlite数据库常用api
(1)int sqlite3_open
编程时要注意用这个打开,没有这个会很离谱的。
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开或者创建一个数据库
参数:
filename 数据库名字
ppdb 操作数据库的指针,句柄。
返回值:
成功 SQLITE_OK
失败 error_code,可以通过sqlite3_errmsg获取错误信息
(2)const char *sqlite3_errmsg
(2)const char *sqlite3_errmsg(sqlite3* db);
功能:获取错误信息描述
(3)int sqlite3_close
(3)int sqlite3_close(sqlite3* db);
功能:关闭一个数据库
(4)int sqlite3_exec
(4)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语句
参数:
db 数据库的句柄指针
sql 将要被执行sql语句
callback 回调函数, 只有在查询语句时,才给回调函数传参
arg 为callback 传参的
errmsg 错误信息的地址
返回值:
成功 SQLITE_OK
出错 errcode 错误码,通过参数errmsg可以输出
***********************************************************
int (*callback)(void* arg ,int ncolumn ,char** f_value,char** f_name)
功能:得到查询结果
参数:
arg 为回调函数传递参数使用的
ncolumn 记录中包含的字段的数目(列数)
f_value 包含每个字段值的指针数组
f_name 包含每个字段名称的指针数组
返回值:
成功 0
出错 非0
*********************************************************
(5)int sqlite3_get_table
(5)int sqlite3_get_table(
sqlite3 *db, /* An open database */
const 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 */
);
功能:查询数据库,它会创建一个新的内存区域来存放查询的结果信息
参数:db 数据库操作句柄
sql 数据库的sql语句
azResult 查询的结果
nRow 行数
nColumn 列数
errmsg 错误消息
返回值:
成功 0
出错 errcode
nrow的值为查询到的符合条件的记录数(不包括字段名)。
ncolumn的值为查询到的符合条件的字段数。
(6)void sqlite3_free_table
(6)void sqlite3_free_table(char **result);
功能:释放内存
代码:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> //sqlite3数据库使用函数时需要包含的头文件
//sqlite3的库是第三方提供的动态库,所以编译时需要手动链接库文件 -lsqlite3
#define DBFILE "stu.db"
#define TABLE "dc21071"
int flags = 0;
void do_insert(sqlite3 *db);
int callback(void *arg, int ncolumn,char **text, char **name);
void do_select(sqlite3 *db);
int main(int argc, char const *argv[])
{
sqlite3 *db;
//创建或者打开一个数据库
if(sqlite3_open(DBFILE, &db) != SQLITE_OK)
{
printf("错误:%s\n", sqlite3_errmsg(db));
exit(1);
}
else
{
printf("成功:数据库已经打开或者创建成功了\n");
}
//创建一张表
char sql[128] = {0};
char *errmsg;
sprintf(sql, "create table %s(id int, name char, sex char, score int)", TABLE);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
else
{
printf("成功:表创建成功\n");
}
char num;
while(1)
{
printf("----------------------------------------------------------\n");
printf("--- 1.插入数据 2.查询数据 3.修改数据 4.删除数据 5.退出 ---\n");
printf("----------------------------------------------------------\n");
printf(">>> ");
scanf("%c", &num);
getchar();
switch(num)
{
case '1':
do_insert(db);
break;
case '2':
flags = 0;
do_select(db);
break;
case '3':
break;
case '4':
break;
case '5':
//关闭数据库
sqlite3_close(db);
exit(0);
break;
default:
printf("您输入的有误,请重新输入\n");
break;
}
}
return 0;
}
void do_insert(sqlite3 *db)
{
int id;
char name[32];
char sex;
int score;
printf("请输入学号:");
scanf("%d", &id);
printf("请输入姓名:");
scanf("%s", name);
getchar();
printf("请输入性别:");
scanf("%c", &sex);
printf("请输入分数:");
scanf("%d", &score);
getchar();
char sql[128] = {0};
char *errmsg;
sprintf(sql, "insert into %s values(%d, '%s', '%c', %d)", TABLE, id, name, sex, score);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
else
{
printf("成功:数据插入成功\n");
}
}
int callback(void *arg, int ncolumn, char **text, char **name)
{
// printf("ncolumn = %d\n", ncolumn);
// printf("text[0] = %s, text[1] = %s\n", text[0], text[1]);
// printf("name[0] = %s, name[1] = %s\n", name[0], name[1]);
int i;
if(flags == 0)
{
for(i = 0; i < ncolumn; i++)
{
printf("%-11s", name[i]);
}
putchar(10);
puts("---------------------------------------");
flags = 1;
}
for(i = 0; i < ncolumn; i++)
{
printf("%-11s", text[i]);
}
putchar(10);
return 0;
}
void do_select(sqlite3 *db)
{
char sql[128] = {0};
char *errmsg;
sprintf(sql, "select * from %s", TABLE);
//sqlite3_exec函数的回调函数在查询的时候会自动根据记录的条数调用很多次
//回调函数每调用一次只获取一行记录的内容
if(sqlite3_exec(db, sql, callback, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
else
{
printf("成功:数据查询成功\n");
}
}
(7)sqlite3_get_table
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const 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 */
);
void sqlite3_free_table(char **result);
以结果表格式为例,假设查询结果如下:
姓名 | 年龄
-----------------------
爱丽丝 | 43
鲍勃 | 28
辛迪 | 21
有两列(M==2)和三行(N==3)。因此,结果表有 8 个条目。假设结果表存储在名为 azResult 的数组中。然后 azResult 保存了这个内容:
azResult[0] = "姓名";
azResult[1] = "年龄";
azResult[2] = "爱丽丝";
azResult[3] = "43";
azResult[4] = "鲍勃";
azResult[5] = "28";
azResult[6] = "辛迪";
azResult[7] = "21";
📣注意通过char ***pazResult
来判定是否查询成功,==没有查到返回0==;
void do_get_table(sqlite3 *db)
{
char sql[128] = {0};
char **ret;
int nrow, ncolumn;
char *errmsg;
sprintf(sql, "select * from %s where id = 1001 and name = 'lisi'", TABLE);
//sqlite3_get_table函数可以查询一条记录是否存在,
//如果存在,第四个参数一定大于0,如果不存在则等于0
if(sqlite3_get_table(db, sql, &ret, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
printf("行数:%d, 列数:%d\n", nrow, ncolumn);
// printf("ret[0] = %s, ret[1] = %s\n", ret[0], ret[1]);
// printf("ret[4] = %s, ret[5] = %s\n", ret[4], ret[5]);
int i, j, n = 0;
for(i = 0; i < nrow + 1; i++)
{
for(j = 0; j < ncolumn; j++)
{
printf("%-11s", ret[n++]);
}
putchar(10);
}
}