SQLite,是一款轻型的数据库,其设计目标是嵌入式的数据库,而且当前在很多嵌入式产品中使用到了sqlite数据库,sqlite数据库占用资源非常的低,对嵌入式设备而言,内存是非常宝贵的,而sqlite数据库可能只需要几百K的内存就够了。
Sqlite数据库还能够支持Windows/Linux/Unix等等主流的操作系统,其跨平台的可移植性特别强,这极大的拓展了其生存的空间。
同时能够跟很多程序语言相结合,比如C#、PHP、Java,C等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快,比起Oracle数据库来说,免费也是极大的优势。
SQLite第一个Alpha版本诞生于2000年5月,至2018年已经有18个年头, SQLite 3也已经发布,并成功的进入了我们的事业。
除了上面提到的低内存占用率、跨平台可移植性、多语言支持、免费开源,sqlite3数据库还有强大的功能,比如支持数据库大小可达2TB,十多万行的代码非常适合学习,良好的代码注释等等。
那么我们学习数据库好可以快速的入门,在门外徘徊太久的话会挫伤我们学习的积极性。如果你是一个嵌入式的学习和开发者,那么从以下两个方面出发可以帮你快速的上手sqlite3数据库:
1、Sqlite3的命令 :数据库的创建及增删改查
2、2、sqlite3 API函数接口:用API接口实现数据库的创建及增删改查
当然了,以下是基于Ubuntu平台做的测试:
1-- 安装数据库:
在线安装:sudo apt-get install sqlite sqlite3
sudo apt-get install libsqlite3-dev
sudo apt-get install sqlitebrowser
离线安装:
下载安装下面三个包:
libsqlite3-0_3.7.2-1ubuntu0.1_i386.deb
libsqlite3-dev_3.7.2-1ubuntu0.1_i386.deb
sqlite3_3.7.2-1ubuntu0.1_i386.deb
sudo dpkg -i *.deb (数据库安装文件)
2、Sqlite3的命令
2.1、创建数据库
sqlite3 stu.db
必须指定数据库名字
2.2、sqlite命令
系统命令 以 "."开头
普通命令 ,以";"结束
.schema 查看表的结构
.quit 退出数据库
.exit 退出数据库
.help 查看帮助信息
.databases 查看数据库
.tables 显示数据库中所有的表的表名
2.3、sqlite3 的使用 : 增删改查
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;
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);
3、sqlite3 API 函数接口:
学习API函数接口,那么首先要掌握函数接口的三要素: 功能--参数--返回值,
然后就是写代码去验证我们队函数的理解,然后将函数用到实际的项目开发当中
(1)int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开一个数据库
参数:filename 数据库名字
ppdb 操作数据库的指针,句柄。
返回值:成功 SQLITE_OK , 失败 error_code
(2)const char *sqlite3_errmsg(sqlite3* db);
功能:获取错误信息描述
(3)int sqlite3_close(sqlite3* db);
功能:关闭一个数据库
(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 错误码
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(
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的值为查询到的符合条件的字段数。
注意:nrow的值不包括字段名,如果打印时用for (i = 0; i < nrow; i++)会打印出字段名,但是会少打印出一条符合条件的记录。
因此打印时要用 for (i = 0; i
(6)void sqlite3_free_table(char **result);
功能:释放内存
4、下面我们先来测一下sqlite命令的使用:
fengjunhui@ubuntu:~/Sqlite$ sqlite3 fengjunhui.db
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table stu(id int,name char,sex char,score int);
sqlite> insert into stu values(1001,'fengjunhui','m',88);
1001|fengjunhui|m|88
1002|liuxiaofan|m|92
1003|luzhengyu|m|96
1004|xiaohui|m|86
sqlite> select * from stu where name=fengjunhui ;
Error: no such column: fengjunhui ----注意类型匹配
sqlite> select * from stu where name = 'fengjunhui';
1001|fengjunhui|m|88
sqlite> select * from stu where id=1003;
1003|luzhengyu|m|96
sqlite> update stu set sex = f where id=1002;
Error: no such column: f
sqlite> update stu set sex ='f' where id=1002;
sqlite> select * from stu
...> ;
1001|fengjunhui|m|88
1002|liuxiaofan|f|92
1003|luzhengyu|m|96
1004|xiaohui|m|86
sqlite> delete from stu where name='xiaohui';
sqlite> select * from stu;
1001|fengjunhui|m|88
1002|liuxiaofan|f|92
1003|luzhengyu|m|96
sqlite> alter table stu add column age int;
sqlite> select * from stu ;
1001|fengjunhui|m|88|
1002|liuxiaofan|f|92|
1003|luzhengyu|m|96|
sqlite> update stu set age = 25 where id=1001;
sqlite> select * from stu;
1001|fengjunhui|m|88|25
1002|liuxiaofan|f|92|
1003|luzhengyu|m|96|
sqlite> create table stu_bak as select id,name,sex,score from stu;
sqlite> .table
stu stu_bak
sqlite> .schema
CREATE TABLE stu(id int,name char,sex char,score int, age int);
CREATE TABLE stu_bak(
id INT,
name TEXT,
sex TEXT,
score INT
);
sqlite> drop table stu;
sqlite> alter table stu_bak rename to stu;
sqlite> .table
stu
sqlite> create table usr(name text primary key,passwd text);
sqlite> .talbe
Error: unknown command or invalid arguments: "talbe". Enter ".help" for help
sqlite> .table
stu usr
5、sqlite3 API函数接口的使用
测试源码:
#include
#include
//注意:编译时需要手动链接库文件 -lsqlite3
#define DATABASE "student.db"
#define N 128
#define IS_NUM(index) (0 <= index && index <= 9) ? 1 : 0
int flags = 0;
int do_insert(sqlite3 *db)
{
int id;
char name[N];
int score;
char sql[N];
char *errmsg;
printf("please input id >>> ");
scanf("%d", &id);
getchar();
printf("please input name >>> ");
scanf("%s", name);
getchar();
printf("please input score >>> ");
scanf("%d", &score);
getchar();
sprintf(sql, "insert into stu values(%d, '%s', %d)", id, name, score);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("the datas is inserted successfully\n");
}
return 0;
}
//回调函数负责得到查询的结果
int callback(void *arg, int ncolumn, char **f_value, char **f_name)
{
int i = 0;
if(flags == 0)
{
for(i = 0; i < ncolumn; i++)
{
printf("%-11s", f_name[i]);
}
putchar(10);
flags = 1;
}
for(i = 0; i < ncolumn; i++)
{
printf("%-11s", f_value[i]);
}
putchar(10);
return 0;
}
//查询数据
int do_select(sqlite3 *db)
{
char *errmsg;
if(sqlite3_exec(db, "select * from stu", callback, NULL, &errmsg) != SQLITE_OK){
printf("%s\n", errmsg);
}else{
printf("the datas is selected successfully\n");
}
return 0;
}
int do_update(sqlite3* db)
{
int id,score;
char name[N]={0},columnname[N]={0},columntype[N]={0};
int num,index;
char* errmsg;
char sql[N]={0};
printf("input your index for search: 1 id 2 name 3 score: \n");
scanf("%d",&index);
getchar();
if(index == 1){
printf("input id : \n");
scanf("%d",&id);
}else if(index == 2){
printf("input name : \n");
scanf("%s",name);
}else {
printf("input score: \n");
scanf("%d",&score);
}
printf("your choice whose info to update: 1 id 2 name 3 score 4 colum: \n");
scanf("%d",&num);
getchar();
switch(num)
{
case 1:
printf("please input id: ");
scanf("%d",&id);
getchar();
if(index == 1){
printf("input sorry,the same info,no need change.\n ");
}else if(index == 2){
sprintf(sql,"update stu set id=%d where name='%s'",id,name);
}else if(index == 3){
sprintf(sql,"update stu set id=%d where score=%d",id,score);
}if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){
printf("%s\n",errmsg);
}
break;
case 2:
printf("please input name: ");
scanf("%s",name);
getchar();
if(index == 1){
sprintf(sql,"update stu set name=%s where id='%d'",name,id);
}if(index == 2){
printf("input sorry,the same info,no need change.\n ");
}else if(index == 3){
sprintf(sql,"update stu set name=%s where score=%d",name,score);
}if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){
printf("%s\n",errmsg);
}
break;
case 3:
printf("please input socre: ");
scanf("%d",&score);
getchar();
if(index == 1) {
sprintf(sql,"update stu set score=%d where id='%d'",score,id);
}else if(index == 2){
sprintf(sql,"update stu set score=%d where name=%s",score,name);
} else if(index == 3){
printf("input sorry,the same info,no need change.\n ");
}
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){
printf("%s\n",errmsg);
}
break;
case 4:
printf("please input column name: ");
scanf("%s",columnname);
getchar();
printf("please input column type: INT or CHAR");
scanf("%s",columntype);
getchar();
sprintf(sql,"alter table stu add column '%s' '%s' '",columnname,columntype);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){
printf("%s\n",errmsg);
}
break;
default:
printf("input illegal.\n");
}
printf("the datas is update successfully\n");
return 0;
}
int do_delete(sqlite3* db)
{
int i=0;
char table[N]={0};
int id,score,index;
char name[N]={0};
char* errmsg;
char sql[N]={0};
char *delsql[5]={0};
printf("\n");
do_select(db); //printf database info list
printf("\n");
printf("input index for delete: 1 id 2 name 3 score 4 table 5 colum: \n");
scanf("%d",&index);
getchar();
if(index == 1){
printf("input id : \n");
scanf("%d",&id);
sprintf(sql,"delete from stu where id=%d",id);
}else if(index == 2){
printf("input name : \n");
scanf("%s",name);
sprintf(sql,"delete from stu where name=%s",name);
}else if(index == 3){
printf("input score: \n");
scanf("%d",&score);
sprintf(sql,"delete from stu where score=%d",score);
}else if(index == 4){
printf("input which table: \n");
scanf("%s",table);
sprintf(sql,"drop table %s",table);
}else if(index == 5){
#if 0
sprintf(delsql[0],"create table stu1 as select id,name from stu\n");
sprintf(delsql[1],"drop table stu\n");
sprintf(delsql[2],"alter table stu1 rename to stu\n");
#endif
delsql[0] = "create table stu1 as select id,name from stu";
delsql[1] = "drop table stu";
delsql[2] = "alter table stu1 rename to stu";
for(i = 0;i < 3;i ++){
printf("delsql[%d]: %s\n",i,delsql[i]);
}
return 0;
}
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){
printf("%s\n",errmsg);
}
return 0;
}
int main(int argc, const char *argv[])
{
sqlite3 *db;
char *errmsg;
int num;
//创建(打开)数据库
if(sqlite3_open(DATABASE, &db) != SQLITE_OK) {
printf("%s\n", sqlite3_errmsg(db));
}else{
printf("the database is opened successfully\n");
}
//创建一张表
if(sqlite3_exec(db, "create table stu(id int, name char, score int)", NULL, NULL, &errmsg) != SQLITE_OK){
printf("%s\n", errmsg);
}else {
printf("the table is created successfully\n");
}
//对当前表进行增删改查
while(1)
{
printf("\n");
printf("***1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出***\n");
printf("\n");
printf(">>> ");
scanf("%d", &num);
getchar();
switch(num)
{
case 1:
do_insert(db);
break;
case 2:
flags = 0;
do_select(db);
//do_select_get_table(db);
break;
case 3:
do_update(db);
break;
case 4:
do_delete(db);
break;
case 5:
sqlite3_close(db);
return -1;
default:
printf("please input correct option\n");
}
}
return 0;
}
测试结果:
fengjunhui@ubuntu:~/Sqlite$ ./a.out
the database is opened successfully
table stu already exists
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 2
id name score
1001 liuxiaofan 92
1004 fengjunhui 98
1003 luzhengyu 96
the datas is selected successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 1
please input id >>> 1005
please input name >>> xiaohuihui
please input score >>> 76
the datas is inserted successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 3
input your index for search: 1 id 2 name 3 score:
1
input id :
1004
your choice whose info to update: 1 id 2 name 3 score 4 colum:
3
please input socre: 88
the datas is update successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 2
id name score
1001 liuxiaofan 92
1004 fengjunhui 88
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 4
1001 liuxiaofan 92
1004 fengjunhui 88
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
input index for delete: 1 id 2 name 3 score 4 table 5 colum:
2
input name :
fengjunhui
no such column: fengjunhui
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 2
id name score
1001 liuxiaofan 92
1004 fengjunhui 88
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 5
fengjunhui@ubuntu:~/Sqlite$ gcc 5_student.c -lsqlite3
fengjunhui@ubuntu:~/Sqlite$ ./a.out
the database is opened successfully
table stu already exists
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 4
id name score
1001 liuxiaofan 92
1004 fengjunhui 88
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
input index for delete: 1 id 2 name 3 score 4 table 5 colum:
2
input name :
'fengjunhui'
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 2
id name score
1001 liuxiaofan 92
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 5
fengjunhui@ubuntu:~/Sqlite$ gcc 5_student.c -lsqlite3
fengjunhui@ubuntu:~/Sqlite$ ./a.out
the database is opened successfully
table stu already exists
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 4
id name score
1001 liuxiaofan 92
1003 luzhengyu 96
1005 xiaohuihui 76
the datas is selected successfully
input index for delete: 1 id 2 name 3 score 4 table 5 colum:
5
delsql[0]: create table stu1 as select id,name from stu
delsql[1]: drop table stu
delsql[2]: alter table stu1 rename to stu
1:插入数据 2:查询数据 3:修改数据 4:删除数据 5:退出
>>> 5
扩展内容:
sqlite3支持的数据类型:
NULL、INTEGER、REAL、TEXT、BLOB
但是,sqlite3也支持如下的数据类型
smallint 16位整数
integer 32位整数
decimal(p,s) p是精确值,s是小数位数
float 32位实数
double 64位实数
char(n) n长度字符串,不能超过254
varchar(n) 长度不固定大字符串长度为n,n不超过4000
graphic(n) 和 char(n) 一样,但是单位是两个字符double-bytes,n不超过127(中文字)
vargraphic(n) 可变长度且大长度为n
date 包含了年份、月份、日期
time 包含了小时、分钟、秒
timestamp 包含了年、月、日、时、分、秒、千分之一秒
sqlite3支持的函数
【1】日期函数
datetime() : 产生日期和时间
date(): 产生日期
time():产生时间
strftime():对以上3个函数产生的日期和时间进行格式化
用法实例:
1、select date('2011-9-9','+1 day','+1 year'); 结果是 2010-09-10
2、select datetime('now'); 当前日期和时间
3、select datetime('now', 'start of month'); 本月的第一天零点,也可以设置年和日的第一天
4、select datetime('now','+1 hour','-12 minute'); 当前时间加48分钟
strftime()函数可以将YYYY-MM-DD HH:MM:SS格式的日期字符串转换为其它形式的字符串
%d:天数,01-31
%f :小数形式的秒,SS.SSS
%H:小时
%j :某一天是该年的第几天,001-366
%m:月份,00-12
%M:分钟,00-59
%s:从1970到现在的秒数
%S:秒,00-59
%w:星期,0-6,0是星期天
%W:某天是该年的第几周,01-53
%Y:年,YYYY
%% 百分号
应用举例:
select strftime('%Y.%m.%d %H:%M:%S','now','localtime');
二、【算术函数】
abs(X):返回绝对值
max(X,Y[,...]):返回大值
min(X,Y,[,...]):返回小值
random(*):返回随机数
round(X[,Y]): 四舍五入
三、【字符串处理函数】
length(x) :返回字符串字符个数
lower(x) :大写转小写
upper(x):小写转大写
substr(x,y,Z):截取子串
like(A,B):确定给定的字符串与指定的模式是否匹配