嵌入式数据库 SQLite 浅析

  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

sqlite > .quit



2、SQL命令

       每个命令以 ;结束

1)创建新表

      sqlite > create table <table_name> (f1 type1, f2 type2,...);


type为数据类型:

NULL

INTEGER

REAL

TEXT

BLOB

注意:若未指定类型,默认是字符串,向表中添加新纪录时要加 “”;


2)删除表

 sqlite > drop table <table_name>;


可以看到原来有两个表 user与user2 ,使用 drop  table user2 后可以看到 只剩下 user;


3)查询表中所有记录

 sqlite >select * from <table_name>;



4) 按指定条件查询表中记录

sqlite >select * from <table_name> where <expression>;


这里的条件是 id < 2 ,可以看到 id < 3 的数据被挑选出来;


5)向表中添加新纪录

sqlite >insert into <table_name> values(value1,value2,...);


可以看到最新的记录被添加进去;


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)在表中添加字段

sqlite > alter table <table> add column <field><type> defalut... ;


可以看到 age 被添加进去;


三、SQLite 编程接口

1、打开sqlite 数据库 sqlite3_open

函数原型:

[cpp] view plaincopy
  1. int sqlite3_open(const char *fileName, sqlite3 **ppDB);   

函数功能:打开一个数据库;若该数据库文件不存在,则自动创建。打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行。 

输入参数:fileName,待打开的数据库文件名称,包括路径,以’\0’结尾;特别说明:SQLite支持内存数据库,内存方式存储使用文件名“:memory:” 

输出参数ppDB,返回打开的数据库句柄;

返回值:执行成功返回SQLITE_OK,否则返回其他值;


2、关闭 sqlite 数据库sqlite3_close

 函数原型:

[cpp] view plaincopy
  1. int sqlite3_close(sqlite3 *pDB);  

函数功能:关闭一个打开的数据库;

输入参数:pDB,打开的数据库句柄

输出参数:无 

返回值:执行成功返回SQLITE_OK,否则返回其他值


3、sqlite3_errmsg

函数原型:

[cpp] view plaincopy
  1. const char *sqlite3_errmsg(sqlite3 *pDB);  

函数功能:获取最近调用的API接口返回的错误说明,这些错误信息UTF-8的编码返回,并且在下一次调用任何SQLiteAPI函数时被自动清除;

输入参数:pDB,打开的数据库句柄

输出参数:

返回值:错误说明的字符串指针


4、sqlite3_exec

函数原型:

[cpp] view plaincopy
  1. int sqlite3_exec(sqlite3 *pDB,constchar *sql,  
  2.                     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 plaincopy
  1. typedef int(*sqlite_callback)(void*para,int columnCount,  
  2.                                  char **columnValue,char **columnName);  
函数功能: 由用户处理查询的结果

[cpp] view plaincopy
  1. 回调函数的格式如下:  
  2. int sqlite_callback(  
  3.     void* pv,    /* 由 sqlite3_exec() 的第四个参数传递而来 */  
  4.     int argc,        /* 表的列数 */  
  5.     char** argv,    /* 指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到 */  
  6.     char** col        /* 指向表头名的指针数组, 可以由 sqlite3_column_name() 得到 */  
  7. );  
  8.   
  9. 参数格式:  
  10.     传给sqlite3_exec的回调函数,用来显示查询结果  
  11.     对每一条查询结果调用一次该回调函数  
  12. 参数:  
  13.     pv:由sqlite3_exec传递的初始化参数  
  14.     argc:表头的列数  
  15.     col:表头的名字数组指针  
  16.     argv:表头的数据数组指针  
  17. 返回值:  
  18.     1:中断查找  
  19.     0:继续列举查询到的数据  
  20. 示例表:  
  21. +-----------------------------------+  
  22. |  id  |  pic   |  data(16进制数据)  |  
  23. |-----------------------------------|  
  24. |   1  |  a.jpg |      00 00 00 ... |  
  25. |-----------------------------------|  
  26. |   2  |  b.jpg |     XX XX XX      |  
  27. +-----------------------------------+  
  28. 对第一行数据:  
  29.     argc=3 即 [0]...[2]  
  30.     argv[0]="1",argv[1]="a.jpg",argv[2]="00 00 00..."(实际16进制数据,非这里显示的字符串形式)  
  31.     col[0]="id",col[1]="pic",col[2]="data"  
  32.    
  33. 说明:  
  34.     sqlite3_exec() 的回调函数必须按照此格式, 当然形参的名字任意.  
  35.     如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)argv[i].  
  36.     该回调函数有两种返回值类型.  
  37.         1.返回零:sqlite3_exec() 将继续执行查询.  
  38.         2.返回非零:sqlite3_exec()将立即中断查询, 且 sqlite3_exec() 将返回 SQLITE_ABORT.  
  39. 示例:  
  40.     int i;  
  41.     for(i=0; i<argc; i++)  
  42.     {  
  43.         printf("%s\t%s\n\n", col[i], argv[i]);  
  44.     }  


下面是个实例:

[cpp] view plaincopy
  1. #include <sqlite3.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <string.h>  
  5.   
  6. #define MAX 100  
  7.   
  8. int show_sql_result(  
  9.     void *arg,   
  10.     int n_column,   
  11.     char **column_value,   
  12.     char **column_name  
  13.     )  
  14. {  
  15.     int i = 0;  
  16.       
  17.     int param = *((int *)arg);  
  18.       
  19.     printf("enter callback ---> param = %d, n_column = %d\n", param, n_column);  
  20.       
  21.     for(i = 0; i < n_column; i++) {  
  22.         printf("%s|", column_name[i]);  
  23.     }  
  24.     printf("\b \n");  
  25.       
  26.     for(i = 0; i < n_column; i++) {  
  27.         printf("%s|", column_value[i]);  
  28.     }  
  29.     printf("\b \n");  
  30.       
  31.     return 0;  
  32. }  
  33.   
  34. int exec_sql(char *sql_string, sqlite3 *db)  
  35. {  
  36.     char *errmsg = NULL;  
  37.       
  38.     int param = 100;  
  39.       
  40.     printf("before sqlite3_exec()\n");  
  41.     if( SQLITE_OK != sqlite3_exec(  
  42.             db,     /* handler to the db connection */  
  43.             sql_string,     /* SQL statements */  
  44.             show_sql_result,/* callback */   
  45.             ¶m,     /* param to the callback */  
  46.             &errmsg)) { /* error message holder,  
  47.                      * NULL means you don't want it  
  48.                      */  
  49.         if (NULL != errmsg) {  
  50.             fprintf(stderr, "sqlite3_exec(%s): %s.\n",   
  51.                 sql_string, errmsg);  
  52.             sqlite3_free(errmsg);  
  53.         }  
  54.         else {  
  55.             fprintf(stderr, "sqlite3_exec(%s): error.\n",   
  56.                 sql_string);  
  57.         }  
  58.         return 1;  
  59.     }  
  60.     printf("after sqlite3_exec()\n");  
  61.       
  62.     return 0;  
  63. }  
  64.   
  65. int main(int argc, char *argv[])  
  66. {  
  67.     sqlite3 *db = NULL;  
  68.     int result;  
  69.     char sql_buf[MAX];  
  70.       
  71.     if (argc < 2) {  
  72.         fprintf(stderr, "usage : %s <db file>.\n", argv[0]);  
  73.         exit(EXIT_FAILURE);  
  74.     }  
  75.       
  76.     result = sqlite3_open(argv[1], &db);  
  77.     if (result != SQLITE_OK) {  
  78.         if (NULL != db) {  
  79.             fprintf(stderr, "sqlite3_open %s : %s.\n",  
  80.                 argv[1], sqlite3_errmsg(db));  
  81.         }   
  82.         else {  
  83.             printf("error : failed to allocate memory for sqlite3!\n");  
  84.         }  
  85.           
  86.         sqlite3_close(db);  
  87.           
  88.         exit(EXIT_FAILURE);  
  89.     }  
  90.       
  91.     while(1) {  
  92.         printf("sqlite> ");  
  93.         if (NULL == fgets(sql_buf, sizeof(sql_buf), stdin))  
  94.             continue;  
  95.         sql_buf[strlen(sql_buf) - 1] = '\0'/* eat up the ending '\n' */  
  96.                   
  97.         if(strncmp(sql_buf, ".quit", 5) == 0)  
  98.             break;  
  99.           
  100.         exec_sql(sql_buf, db);  
  101.     }  
  102.       
  103.     result = sqlite3_close(db);  
  104.     if (result != SQLITE_OK) {  
  105.         fprintf(stderr, "sqlite3_close %s: %s.\n",  
  106.             argv[1], sqlite3_errmsg(db));  
  107.         exit(EXIT_FAILURE);  
  108.     }  
  109.       
  110.     exit(EXIT_SUCCESS);  
  111. }  
编译:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/SQLite/pro$ gcc -o test demo2.c -lsqlite3  


执行结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/SQLite$ ./test message.db   
  2. sqlite> select * from user;  
  3. before sqlite3_exec()  
  4. enter callback ---> param = 100, n_column = 4  
  5. id|name|num|age   
  6. 1|Kobe|5|(null)   
  7. enter callback ---> param = 100, n_column = 4  
  8. id|name|num|age   
  9. 2|James|2|(null)   
  10. enter callback ---> param = 100, n_column = 4  
  11. id|name|num|age   
  12. 3|Jorden|6|(null)   
  13. after sqlite3_exec()  
  14. sqlite> update user set age=36 where id=1;  
  15. before sqlite3_exec()  
  16. after sqlite3_exec()  
  17. sqlite> select *from user  
  18. before sqlite3_exec()  
  19. enter callback ---> param = 100, n_column = 4  
  20. id|name|num|age   
  21. 1|Kobe|5|36   
  22. enter callback ---> param = 100, n_column = 4  
  23. id|name|num|age   
  24. 2|James|2|(null)   
  25. enter callback ---> param = 100, n_column = 4  
  26. id|name|num|age   
  27. 3|Jorden|6|(null)   
  28. after sqlite3_exec()  
  29. sqlite> .quit  
  30. fs@ubuntu:~/qiang/SQLite$  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

socket 请求Web服务器过程

HTTP协议只是一个应用层协议&#xff0c;它底层是通过TCP进行传输数据的。因此&#xff0c;浏览器访问Web服务器的过程必须先有“连接建立”的发生。 而有人或许会问&#xff1a;众所周知&#xff0c;HTTP协议有两大特性&#xff0c;一个是“无连接”性&#xff0c;一个是“无状…

有些事情现在不做一辈子就都不会做了

这句话最近一直印在我的脑海里。这句话最早是在Casperkid的百度空间里面看见的&#xff0c;那时他生日。作为师傅的刺&#xff08;道哥&#xff09;送了他自己写的一本《白帽子讲WEB安全》给他&#xff0c;并在扉页上写着这句话。那时一看到这句话&#xff0c;仿佛有种触电的感…

HTTP 数据包头解析

一、连接至Web服务器 一个客户端应用&#xff08;如Web浏览器&#xff09;打开到Web服务器的HTTP端口的一个套接字&#xff08;缺省为80&#xff09;。 例如&#xff1a;http://www.myweb.com:8080/index.html 在Java中&#xff0c;这将等同于代码&#xff1a; [java] view pla…

Shell 脚本中如何使用make命令

最近开发的项目中需要编写Shell脚本对整个工程进行自动化编译&#xff0c;即在Shell脚本中使用make命令来进行编译&#xff0c;下面回顾一下Shell脚本中如何使用make命令&#xff09; 在开发一个系统时&#xff0c;一般是将一个系统分成几个模块&#xff0c;这样做提高了系统的…

Shell 脚本知识回顾 (六) —— Shell 函数

一、Shell函数&#xff1a;Shell函数返回值、删除函数、在终端调用函数 函数可以让我们将一个复杂功能划分成若干模块&#xff0c;让程序结构更加清晰&#xff0c;代码重复利用率更高。像其他编程语言一样&#xff0c;Shell 也支持函数。Shell 函数必须先定义后使用。 Shell 函…

Shell 脚本知识回顾 (五) —— Shell 循环

一、Shell for循环 与其他编程语言类似&#xff0c;Shell支持for循环。 for循环一般格式为&#xff1a;for 变量 in 列表 docommand1command2...commandN done 列表是一组值&#xff08;数字、字符串等&#xff09;组成的序列&#xff0c;每个值通过空格分隔。每循环一次&…

Shell 脚本知识回顾 (四) —— Shell 命令及Shell 相关语句

一、Shell echo命令 echo是Shell的一个内部指令&#xff0c;用于在屏幕上打印出指定的字符串。命令格式&#xff1a;echo arg您可以使用echo实现更复杂的输出格式控制。 显示转义字符 echo "\"It is a test\""结果将是&#xff1a;"It is a test"…

Shell 脚本知识回顾 (三) —— 替换、运算符、字符串、数组

一、Shell替换&#xff1a;Shell变量替换&#xff0c;命令替换&#xff0c;转义字符 如果表达式中包含特殊字符&#xff0c;Shell 将会进行替换。例如&#xff0c;在双引号中使用变量就是一种替换&#xff0c;转义字符也是一种替换。 举个例子&#xff1a; [cpp] view plaincop…

Shell 脚本知识回顾 (二) —— Shell变量

一、Shell变量&#xff1a;Shell变量的定义、删除变量、只读变量、变量类型 Shell支持自定义变量。定义变量 定义变量时&#xff0c;变量名不加美元符号&#xff08;$&#xff09;&#xff0c;如&#xff1a; [cpp] view plaincopy variableName"value" 注意&…

Shell 脚本知识回顾 (一) —— 基础篇

一、Shell简介&#xff1a;什么是Shell&#xff0c;Shell命令的两种执行方式 Shell本身是一个用C语言编写的程序&#xff0c;它是用户使用Unix/Linux的桥梁&#xff0c;用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言&#xff0c;又是一种程序设计语言。作为命令…

红帽集群RHCS

1、简介&#xff1a;RHCS是RedHatClusterSuite的缩写&#xff0c;也就是红帽子集群套件&#xff0c;RHCS是一个能够提供高可用性、高可靠性、负载均衡、存储共享且经济廉价的集群工具集合&#xff0c;它将集群系统中三大集群架构融合一体&#xff0c;可以给web应用、数据库应用…

Java 基础——数组解析

数组对于每一门编辑应语言来说都是重要的数据结构之一&#xff0c;当然不同语言对数组的实现及处理也不尽相同。 Java语言中提供的数组是用来存储固定大小的同类型元素。 可以声明一个数组变量&#xff0c;如numbers[100]来代替直接声明100个独立变量number0&#xff0c;number…

《在你身边,为你设计》-哪位知道下载、在线阅读地址啊?

《在你身边&#xff0c;为你设计》-前端UI必读出自腾讯CDChttp://cdc.tencent.com/?p6761今天听同事说这本书写的非常好&#xff0c;改变了他关于前端UI的许多看法&#xff0c;可谓&#xff1a;醍醐灌顶。可惜我网上找了下都需要Money买&#xff0c;哪位有在线阅读、PDF下载地…

一、OpenStack架构

DashBoardHorizon提供WEB界面ComputerNova计算也就是虚拟机NetworkingNeutron提供给nova网络支持Object StorageSwift提供对象存储Block StorageCinder提供云硬盘给nova&#xff0c;同时备份到SwiftIdentity SserviceKeystone提供所有组件的认证Image ServiceGlance提供给nova镜…

Java 三大特性 —— 多态

Java中多态性的实现 一、什么是多态 1.面向对象的三大特性&#xff1a;封装、继承、多态。从一定角度来看&#xff0c;封装和继承几乎都是为多态而准备的。这是我们最后一个概念&#xff0c;也是最重要的知识点。 2.多态的定义&#xff1a;指允许不同类的对象对同一消息做出响应…

linux /proc/cpuinfo文件分析

为什么80%的码农都做不了架构师&#xff1f;>>> 基于不同指令集&#xff08;ISA&#xff09;的CPU产生的/proc/cpuinfo文件不一样&#xff0c;基于X86指令集CPU的/proc/cpuinfo文件包含如下内容&#xff1a; processor  &#xff1a; 0vendor_id  &#xff1a;…

Java 高级类(下) —— 内部类和匿名类

Java内部类&#xff08;Inner Class&#xff09;&#xff0c;类似的概念在C里也有&#xff0c;那就是嵌套类&#xff08;Nested Class&#xff09;&#xff0c;乍看上去内部类似乎有些多余&#xff0c;它的用处对于初学者来说可能并不是那么显著&#xff0c;但是随着对它的深入…

Java 高级类(上) —— 抽象类和接口

在面向对象的概念中&#xff0c;我们知道所有的对象都是通过类来描绘的&#xff0c;但是并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类。 抽象类往往用来表征我们在对问题领域进行分析、 设…

【Git入门之五】版本管理

2019独角兽企业重金招聘Python工程师标准>>> 1.版本回退 我们先看一下从项目开始到现在做了什么操作。 [cpp] view plaincopy #总共是4个操作 $ git log --prettyoneline c5c83cfcdb25c67a5c66b4fe3844d0ea912830ec remove JackyData03 a25c58804cb3f4045564fc0e…

Java 进阶——单例模式

一、单例模式概念及特点 Java中单例模式是一种常见的设计模式&#xff0c;单例模式分三种&#xff1a;懒汉式单例、饿汉式单例、登记式单例三种。 单例模式有一下特点&#xff1a; 1、单例类只能有一个实例。 2、单例类必须自己自己创建自己的唯一实例。 3、单例类必须给所有其…