嵌入式数据库 SQLite 浅析
2016-06-19 21:31
288 查看
SQLite是一个非常轻量级自包含(lightweight and self-contained)的DBMS,它可移植性好,很容易使用,很小,高效而且可靠。SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。从外部看,它并不像一个RDBMS,但在进程内部,它却是完整的,自包含的数据库引擎。
嵌入式数据库的一大好处就是在你的程序内部不需要网络配置,也不需要管理。因为客户端和服务器在同一进程空间运行。SQLite 的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite 有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。
下面将介绍SQLite的使用:
一、创建SQLite数据库
1、手工创建
使用sqlite3 工具,通过手工输入SQL命令完成数据库创建,用户在Linux 的命令行界面中输入 sqlite3 可启动 sqlite3工具。
2、代码创建
在代码中动态创建数据库。
在程序执行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序会自动建立数据库,然后打开数据库。
二、SQLite常用命令介绍
1、sqlite3 指令(通常以 . 开头)
1)创建或打开一个数据库文件
在终端下运行 sqlite3 < *.db > 指令:
<*.db> 是要打开的数据库文件。若该文件不存在,则自动创建。
2)显示当前打开的数据库文件
sqlite > .database
可以看到当前打开的数据库文件正是刚刚建立的 message.db文件;
3)显示数据库中所有表名
sqlite > .tables
可以看到当前用户下有一个名为 user 的表;
4)查看表的结构
sqlite > .schema <table_name>
其实这里显示的正是我们创建新表时输入的命令;
5)显示所有命令
sqlite > .help
6) 退出 sqlite3
[b]sqlite > .quit
[/b]
2、SQL命令
每个命令以 ;结束
1)创建新表
sqlite > create table <table_name> (f1 type1, f2 type2,...);
type为数据类型:
NULL
INTEGER
REAL
TEXT
BLOB
注意:若未指定类型,默认是字符串,向表中添加新纪录时要加 “”;
2)删除表
[b] sqlite > drop table <table_name>;
[/b]
可以看到原来有两个表 user与user2 ,使用 drop table user2 后可以看到 只剩下 user;
3)查询表中所有记录
sqlite >select * from <table_name>;
4) 按指定条件查询表中记录
[b]sqlite >select * from <table_name> where <expression>;
[/b]
这里的条件是 id < 2 ,可以看到 id < 3 的数据被挑选出来;
5)向表中添加新纪录
[b]sqlite >insert into <table_name> values(value1,value2,...);
[/b]
可以看到最新的记录被添加进去;
6)按指定的条件删除表中记录
sqlite >delete from <table_name> where <expression>;
可以看到 passwd=1 的被删除;
7) 更新表中记录
sqlite > updata <table_name> set <f1=value1>,<f2=value2>... where <expression>;
可以看到 id=3 的数据被更新。再次提醒,未定义类型的记录默认是字符串,添加时一定要用“” ;
8)在表中添加字段
[b]sqlite > alter table <table> add column <field><type> defalut... ;
[/b]
可以看到 age 被添加进去;
三、SQLite 编程接口
1、打开sqlite 数据库 sqlite3_open
函数原型:
[cpp] view
plain copy
int sqlite3_open(const char *fileName, sqlite3 **ppDB);
函数功能:打开一个数据库;若该数据库文件不存在,则自动创建。打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行。
输入参数:fileName,待打开的数据库文件名称,包括路径,以’\0’结尾;特别说明:SQLite支持内存数据库,内存方式存储使用文件名“:memory:”
输出参数:ppDB,返回打开的数据库句柄;
返回值:执行成功返回SQLITE_OK,否则返回其他值;
2、关闭 sqlite 数据库sqlite3_close
函数原型:
[cpp] view
plain copy
int sqlite3_close(sqlite3 *pDB);
函数功能:关闭一个打开的数据库;
输入参数:pDB,打开的数据库句柄
输出参数:无
返回值:执行成功返回SQLITE_OK,否则返回其他值
3、sqlite3_errmsg
函数原型:
[cpp] view
plain copy
const char *sqlite3_errmsg(sqlite3 *pDB);
函数功能:获取最近调用的API接口返回的错误说明,这些错误信息UTF-8的编码返回,并且在下一次调用任何SQLiteAPI函数时被自动清除;
输入参数:pDB,打开的数据库句柄
输出参数:无
返回值:错误说明的字符串指针
4、sqlite3_exec
函数原型:
[cpp] view
plain copy
int sqlite3_exec(sqlite3 *pDB,constchar *sql,
sqlite_callback callback,void *para,char **errMsg);
函数功能:编译和执行零个或多个SQL语句,查询的结果返回给回调函数callback
输入参数:pDB,数据库句柄;sql,待执行的SQL语句字符串,以’\0’结尾;callback,回调函数,用来处理查询结果,如果不需要回调(比如做insert或者delete操作时),可输入NULL;para,用户传入的参数,可以为NULL,该参数指针最终会被传给回调函数callback,供用户在回调函数中使用;
输出参数:errMsg,返回错误信息,注意是指针的指针。
返回值:执行成功返回SQLITE_OK,否则返回其他值。
5、回调函数sqlite_callback介绍
[cpp] view
plain copy
typedef int(*sqlite_callback)(void*para,int columnCount,
char **columnValue,char **columnName);
函数功能:由用户处理查询的结果
[cpp] view
plain copy
回调函数的格式如下:
int sqlite_callback(
void* pv, /* 由 sqlite3_exec() 的第四个参数传递而来 */
int argc, /* 表的列数 */
char** argv, /* 指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到 */
char** col /* 指向表头名的指针数组, 可以由 sqlite3_column_name() 得到 */
);
参数格式:
传给sqlite3_exec的回调函数,用来显示查询结果
对每一条查询结果调用一次该回调函数
参数:
pv:由sqlite3_exec传递的初始化参数
argc:表头的列数
col:表头的名字数组指针
argv:表头的数据数组指针
返回值:
1:中断查找
0:继续列举查询到的数据
示例表:
+-----------------------------------+
| id | pic | data(16进制数据) |
|-----------------------------------|
| 1 | a.jpg | 00 00 00 ... |
|-----------------------------------|
| 2 | b.jpg | XX XX XX |
+-----------------------------------+
对第一行数据:
argc=3 即 [0]...[2]
argv[0]="1",argv[1]="a.jpg",argv[2]="00 00 00..."(实际16进制数据,非这里显示的字符串形式)
col[0]="id",col[1]="pic",col[2]="data"
说明:
sqlite3_exec() 的回调函数必须按照此格式, 当然形参的名字任意.
如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)argv[i].
该回调函数有两种返回值类型.
1.返回零:sqlite3_exec() 将继续执行查询.
2.返回非零:sqlite3_exec()将立即中断查询, 且 sqlite3_exec() 将返回 SQLITE_ABORT.
示例:
int i;
for(i=0; i<argc; i++)
{
printf("%s\t%s\n\n", col[i], argv[i]);
}
下面是个实例:
[cpp] view
plain copy
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
int show_sql_result(
void *arg,
int n_column,
char **column_value,
char **column_name
)
{
int i = 0;
int param = *((int *)arg);
printf("enter callback ---> param = %d, n_column = %d\n", param, n_column);
for(i = 0; i < n_column; i++) {
printf("%s|", column_name[i]);
}
printf("\b \n");
for(i = 0; i < n_column; i++) {
printf("%s|", column_value[i]);
}
printf("\b \n");
return 0;
}
int exec_sql(char *sql_string, sqlite3 *db)
{
char *errmsg = NULL;
int param = 100;
printf("before sqlite3_exec()\n");
if( SQLITE_OK != sqlite3_exec(
db, /* handler to the db connection */
sql_string, /* SQL statements */
show_sql_result,/* callback */
¶m, /* param to the callback */
&errmsg)) { /* error message holder,
* NULL means you don't want it
*/
if (NULL != errmsg) {
fprintf(stderr, "sqlite3_exec(%s): %s.\n",
sql_string, errmsg);
sqlite3_free(errmsg);
}
else {
fprintf(stderr, "sqlite3_exec(%s): error.\n",
sql_string);
}
return 1;
}
printf("after sqlite3_exec()\n");
return 0;
}
int main(int argc, char *argv[])
{
sqlite3 *db = NULL;
int result;
char sql_buf[MAX];
if (argc < 2) {
fprintf(stderr, "usage : %s <db file>.\n", argv[0]);
exit(EXIT_FAILURE);
}
result = sqlite3_open(argv[1], &db);
if (result != SQLITE_OK) {
if (NULL != db) {
fprintf(stderr, "sqlite3_open %s : %s.\n",
argv[1], sqlite3_errmsg(db));
}
else {
printf("error : failed to allocate memory for sqlite3!\n");
}
sqlite3_close(db);
exit(EXIT_FAILURE);
}
while(1) {
printf("sqlite> ");
if (NULL == fgets(sql_buf, sizeof(sql_buf), stdin))
continue;
sql_buf[strlen(sql_buf) - 1] = '\0'; /* eat up the ending '\n' */
if(strncmp(sql_buf, ".quit", 5) == 0)
break;
exec_sql(sql_buf, db);
}
result = sqlite3_close(db);
if (result != SQLITE_OK) {
fprintf(stderr, "sqlite3_close %s: %s.\n",
argv[1], sqlite3_errmsg(db));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
编译:
[cpp] view
plain copy
fs@ubuntu:~/qiang/SQLite/pro$ gcc -o test demo2.c -lsqlite3
执行结果如下:
[cpp] view
plain copy
fs@ubuntu:~/qiang/SQLite$ ./test message.db
sqlite> select * from user;
before sqlite3_exec()
enter callback ---> param = 100, n_column = 4
id|name|num|age
1|Kobe|5|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
2|James|2|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
3|Jorden|6|(null)
after sqlite3_exec()
sqlite> update user set age=36 where id=1;
before sqlite3_exec()
after sqlite3_exec()
sqlite> select *from user
before sqlite3_exec()
enter callback ---> param = 100, n_column = 4
id|name|num|age
1|Kobe|5|36
enter callback ---> param = 100, n_column = 4
id|name|num|age
2|James|2|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
3|Jorden|6|(null)
after sqlite3_exec()
sqlite> .quit
fs@ubuntu:~/qiang/SQLite$
嵌入式数据库的一大好处就是在你的程序内部不需要网络配置,也不需要管理。因为客户端和服务器在同一进程空间运行。SQLite 的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite 有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。
下面将介绍SQLite的使用:
一、创建SQLite数据库
1、手工创建
使用sqlite3 工具,通过手工输入SQL命令完成数据库创建,用户在Linux 的命令行界面中输入 sqlite3 可启动 sqlite3工具。
2、代码创建
在代码中动态创建数据库。
在程序执行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序会自动建立数据库,然后打开数据库。
二、SQLite常用命令介绍
1、sqlite3 指令(通常以 . 开头)
1)创建或打开一个数据库文件
在终端下运行 sqlite3 < *.db > 指令:
<*.db> 是要打开的数据库文件。若该文件不存在,则自动创建。
2)显示当前打开的数据库文件
sqlite > .database
可以看到当前打开的数据库文件正是刚刚建立的 message.db文件;
3)显示数据库中所有表名
sqlite > .tables
可以看到当前用户下有一个名为 user 的表;
4)查看表的结构
sqlite > .schema <table_name>
其实这里显示的正是我们创建新表时输入的命令;
5)显示所有命令
sqlite > .help
6) 退出 sqlite3
[b]sqlite > .quit
[/b]
2、SQL命令
每个命令以 ;结束
1)创建新表
sqlite > create table <table_name> (f1 type1, f2 type2,...);
type为数据类型:
NULL
INTEGER
REAL
TEXT
BLOB
注意:若未指定类型,默认是字符串,向表中添加新纪录时要加 “”;
2)删除表
[b] sqlite > drop table <table_name>;
[/b]
可以看到原来有两个表 user与user2 ,使用 drop table user2 后可以看到 只剩下 user;
3)查询表中所有记录
sqlite >select * from <table_name>;
4) 按指定条件查询表中记录
[b]sqlite >select * from <table_name> where <expression>;
[/b]
这里的条件是 id < 2 ,可以看到 id < 3 的数据被挑选出来;
5)向表中添加新纪录
[b]sqlite >insert into <table_name> values(value1,value2,...);
[/b]
可以看到最新的记录被添加进去;
6)按指定的条件删除表中记录
sqlite >delete from <table_name> where <expression>;
可以看到 passwd=1 的被删除;
7) 更新表中记录
sqlite > updata <table_name> set <f1=value1>,<f2=value2>... where <expression>;
可以看到 id=3 的数据被更新。再次提醒,未定义类型的记录默认是字符串,添加时一定要用“” ;
8)在表中添加字段
[b]sqlite > alter table <table> add column <field><type> defalut... ;
[/b]
可以看到 age 被添加进去;
三、SQLite 编程接口
1、打开sqlite 数据库 sqlite3_open
函数原型:
[cpp] view
plain copy
int sqlite3_open(const char *fileName, sqlite3 **ppDB);
函数功能:打开一个数据库;若该数据库文件不存在,则自动创建。打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行。
输入参数:fileName,待打开的数据库文件名称,包括路径,以’\0’结尾;特别说明:SQLite支持内存数据库,内存方式存储使用文件名“:memory:”
输出参数:ppDB,返回打开的数据库句柄;
返回值:执行成功返回SQLITE_OK,否则返回其他值;
2、关闭 sqlite 数据库sqlite3_close
函数原型:
[cpp] view
plain copy
int sqlite3_close(sqlite3 *pDB);
函数功能:关闭一个打开的数据库;
输入参数:pDB,打开的数据库句柄
输出参数:无
返回值:执行成功返回SQLITE_OK,否则返回其他值
3、sqlite3_errmsg
函数原型:
[cpp] view
plain copy
const char *sqlite3_errmsg(sqlite3 *pDB);
函数功能:获取最近调用的API接口返回的错误说明,这些错误信息UTF-8的编码返回,并且在下一次调用任何SQLiteAPI函数时被自动清除;
输入参数:pDB,打开的数据库句柄
输出参数:无
返回值:错误说明的字符串指针
4、sqlite3_exec
函数原型:
[cpp] view
plain copy
int sqlite3_exec(sqlite3 *pDB,constchar *sql,
sqlite_callback callback,void *para,char **errMsg);
函数功能:编译和执行零个或多个SQL语句,查询的结果返回给回调函数callback
输入参数:pDB,数据库句柄;sql,待执行的SQL语句字符串,以’\0’结尾;callback,回调函数,用来处理查询结果,如果不需要回调(比如做insert或者delete操作时),可输入NULL;para,用户传入的参数,可以为NULL,该参数指针最终会被传给回调函数callback,供用户在回调函数中使用;
输出参数:errMsg,返回错误信息,注意是指针的指针。
返回值:执行成功返回SQLITE_OK,否则返回其他值。
5、回调函数sqlite_callback介绍
[cpp] view
plain copy
typedef int(*sqlite_callback)(void*para,int columnCount,
char **columnValue,char **columnName);
函数功能:由用户处理查询的结果
[cpp] view
plain copy
回调函数的格式如下:
int sqlite_callback(
void* pv, /* 由 sqlite3_exec() 的第四个参数传递而来 */
int argc, /* 表的列数 */
char** argv, /* 指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到 */
char** col /* 指向表头名的指针数组, 可以由 sqlite3_column_name() 得到 */
);
参数格式:
传给sqlite3_exec的回调函数,用来显示查询结果
对每一条查询结果调用一次该回调函数
参数:
pv:由sqlite3_exec传递的初始化参数
argc:表头的列数
col:表头的名字数组指针
argv:表头的数据数组指针
返回值:
1:中断查找
0:继续列举查询到的数据
示例表:
+-----------------------------------+
| id | pic | data(16进制数据) |
|-----------------------------------|
| 1 | a.jpg | 00 00 00 ... |
|-----------------------------------|
| 2 | b.jpg | XX XX XX |
+-----------------------------------+
对第一行数据:
argc=3 即 [0]...[2]
argv[0]="1",argv[1]="a.jpg",argv[2]="00 00 00..."(实际16进制数据,非这里显示的字符串形式)
col[0]="id",col[1]="pic",col[2]="data"
说明:
sqlite3_exec() 的回调函数必须按照此格式, 当然形参的名字任意.
如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)argv[i].
该回调函数有两种返回值类型.
1.返回零:sqlite3_exec() 将继续执行查询.
2.返回非零:sqlite3_exec()将立即中断查询, 且 sqlite3_exec() 将返回 SQLITE_ABORT.
示例:
int i;
for(i=0; i<argc; i++)
{
printf("%s\t%s\n\n", col[i], argv[i]);
}
下面是个实例:
[cpp] view
plain copy
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
int show_sql_result(
void *arg,
int n_column,
char **column_value,
char **column_name
)
{
int i = 0;
int param = *((int *)arg);
printf("enter callback ---> param = %d, n_column = %d\n", param, n_column);
for(i = 0; i < n_column; i++) {
printf("%s|", column_name[i]);
}
printf("\b \n");
for(i = 0; i < n_column; i++) {
printf("%s|", column_value[i]);
}
printf("\b \n");
return 0;
}
int exec_sql(char *sql_string, sqlite3 *db)
{
char *errmsg = NULL;
int param = 100;
printf("before sqlite3_exec()\n");
if( SQLITE_OK != sqlite3_exec(
db, /* handler to the db connection */
sql_string, /* SQL statements */
show_sql_result,/* callback */
¶m, /* param to the callback */
&errmsg)) { /* error message holder,
* NULL means you don't want it
*/
if (NULL != errmsg) {
fprintf(stderr, "sqlite3_exec(%s): %s.\n",
sql_string, errmsg);
sqlite3_free(errmsg);
}
else {
fprintf(stderr, "sqlite3_exec(%s): error.\n",
sql_string);
}
return 1;
}
printf("after sqlite3_exec()\n");
return 0;
}
int main(int argc, char *argv[])
{
sqlite3 *db = NULL;
int result;
char sql_buf[MAX];
if (argc < 2) {
fprintf(stderr, "usage : %s <db file>.\n", argv[0]);
exit(EXIT_FAILURE);
}
result = sqlite3_open(argv[1], &db);
if (result != SQLITE_OK) {
if (NULL != db) {
fprintf(stderr, "sqlite3_open %s : %s.\n",
argv[1], sqlite3_errmsg(db));
}
else {
printf("error : failed to allocate memory for sqlite3!\n");
}
sqlite3_close(db);
exit(EXIT_FAILURE);
}
while(1) {
printf("sqlite> ");
if (NULL == fgets(sql_buf, sizeof(sql_buf), stdin))
continue;
sql_buf[strlen(sql_buf) - 1] = '\0'; /* eat up the ending '\n' */
if(strncmp(sql_buf, ".quit", 5) == 0)
break;
exec_sql(sql_buf, db);
}
result = sqlite3_close(db);
if (result != SQLITE_OK) {
fprintf(stderr, "sqlite3_close %s: %s.\n",
argv[1], sqlite3_errmsg(db));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
编译:
[cpp] view
plain copy
fs@ubuntu:~/qiang/SQLite/pro$ gcc -o test demo2.c -lsqlite3
执行结果如下:
[cpp] view
plain copy
fs@ubuntu:~/qiang/SQLite$ ./test message.db
sqlite> select * from user;
before sqlite3_exec()
enter callback ---> param = 100, n_column = 4
id|name|num|age
1|Kobe|5|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
2|James|2|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
3|Jorden|6|(null)
after sqlite3_exec()
sqlite> update user set age=36 where id=1;
before sqlite3_exec()
after sqlite3_exec()
sqlite> select *from user
before sqlite3_exec()
enter callback ---> param = 100, n_column = 4
id|name|num|age
1|Kobe|5|36
enter callback ---> param = 100, n_column = 4
id|name|num|age
2|James|2|(null)
enter callback ---> param = 100, n_column = 4
id|name|num|age
3|Jorden|6|(null)
after sqlite3_exec()
sqlite> .quit
fs@ubuntu:~/qiang/SQLite$
相关文章推荐
- jdbc连接mysql数据库小例子(代码)
- 使用 Sphinx 更好地进行 MySQL 搜索
- Oracle 分页查询
- (二)Redis的安装及配置(1)---安装
- MySQL数据库
- 【数据库】数据查询和管理知识点总结
- 数据库
- sql语句特殊字符的截取
- 【mysql索引学习一】mysql索引使用
- ubuntu下mysql的数据导出及导入
- (一)初识Redis内存数据库与持久化
- ubuntu中MySQL的新建用户及远程登录
- [jcc][t4][10120][10898][3.57.82] 操作无效:已关闭 result set。 ERRORCODE=-4470, SQLSTATE=null
- 数据库设计---实现阶段
- TimesTen 应用层数据库缓存学习:18. 利用TimesTen实现Sharding或数据分区
- mongodb3.2 replica sets
- Oracle数据库添表和表空间
- mongodb3.2安装与基本配置
- SQL 循环语句 while 介绍 实例
- Oracle Job Chain