嵌入式工程师必知:SQLite数据库

Posted 松哥的IT小屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式工程师必知:SQLite数据库相关的知识,希望对你有一定的参考价值。


《SQLite3数据库的操作补充》

一、SQLite移植到S5pv210开发板

1、解压源代码包到opt目录下

tar -jxvf sqlite-3.6.12.tar.gz -C /opt/  

2.建立make install目录

mkdir /opt/build

3.进入解压后的文件夹中

cd /opt/sqlite-3.6.12

4.进行配置,生成Makefile

./configure --host = arm-linux-prefix= /opt/build

5.生成Makefile后执行make make install

完成上面的5个操作后,就会在opt/build下生成bin、include、lib、share四个目录。此时需要将bin目录下面的SQLite3拷贝到开发板bin目录下,lib中的内容拷贝到开发板的bin目录中,include是一些头文件,编译的时候才会用到它们,所以不用移植。

6.最后还要修改开发板bin目录下SQLite3权限:

chmod + x sqlite3

7.运行SQLite

./sqlite3 这样就会出现我们熟悉的sqlite3的命令行界面了。


二、SQLite3支持的数据类型

1.NULL,值是NULL

2.BLOB,二进制大对象(BLOB)是任意的类型的数据,BLOB的大小没有限制

3.INTEGER,值是有符号类型,根据值的大小以1,2,3,4,6,8字节存放

4.REAL,值是浮点类型值,以8字节IEEE浮点数存

5.TEXT,值是文本字符串,使用数据库编码(UTF-8、UTF-16BE、UTF-16LE)存放。


三、

在sqlite3的命令行中,可以使用.output 1.txt将数据库的信息存入1.txt文件中。

将数据库导出为ASCII文本文件:

使用".dump"指令可以将整个数据库导出为一个ASCII文本文件。当然也可以导入此文本文件来重建数据库,例如:

$ echo '.dump' | sqlite3 ex1 | gzip -c >ex1.dump.gz

这句语句会产生一个名叫"ex1.dump.gz"的文件,它包含在另一台机器重建数据库exl需要的所有信息。重建数据库:

$ zcat ex1.dump.gz | sqlite3 ex2  这样就重建了ex1数据库,以ex2命名。                                                                                                                                                                                                                                      

四、常用的SQLite的C语言接口

(1)int sqlite3_open {

const char * filename;//数据库名字,可以用中文,但是还是尽量用英文

sqlite3 **ppDb; //数据库连接句柄

}


(2)int sqlite3_close(sqlite3 *)


(3)返回"sqlite3"对象的错误信息

const char * sqlite3_errmsg(sqlite3 *)


例1:

#include <stdio.h>

#include <sqlite3.h>


int main()

{

int ret = -1;

sqlite3 * db = NULL;//定义一个数据库连接对象指针

ret = sqlite3_open("1.db",&db);

if(ret == SQLITE_OK)

{

printf("open db success!!\n");

}

else

{

fprintf(stderr,"failure %S \n",sqlite3_errmsg(db));//获取连接对象的错误信息

return -1;

}

sqlite3_close(db);

return 0;

}


(4)执行一条SQL语句

SQLITE_API int sqlite3_exec(

  sqlite3*,                                  /* 打开的数据库句柄 */

  const char *sql,                           /* SQL 语句 */

  int (*callback)(void*,int,char**,char**),  /* 回调函数 */

  void *,                                    /* 回调函数的第一个参数 */

  char **errmsg                              /* 错误信息 */

);

例2:

#include <stdio.h>

#include <sqlite3.h>


int main()

{

int ret = -1;

sqlite3 * db = NULL;//定义一个数据库连接对象指针

char * errmsg = NULL;

ret = sqlite3_open("1.db",&db);

if(ret == SQLITE_OK)

{

printf("open db success!!\n");

}

else

{

fprintf(stderr,"failure %S \n",sqlite3_errmsg(db));//获取连接对象的错误信息

return -1;

}

char *sql = "insert into test_table values("liman","female","18");"//插入表操作

ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);

if(ret != SQLITE_OK)

{

fprintf(stderr,"failure %S \n",errmsg);//获取连接对象的错误信息

return -1;

}

else

{

printf("exec success!!\n");

sqlite3_close(db);

}

return 0;

}

(5)查询数据库 

SQLITE_API int sqlite3_get_table(

  sqlite3 *db,          /* 打开的数据库句柄 */

  const char *zSql,     /* SQL 语句 */

  char ***pazResult,    /* Results of 返回的结果集*/

  int *pnRow,           /* 返回的结果集中包含的总行数 */

  int *pnColumn,        /* 返回的结果集中包含的总列数 */

  char **pzErrmsg       /* Error错误信息 */

);

(6)释放处理后的结果集

SQLITE_API void sqlite3_free_table(char **result);


例3:遍历数据库中的内容:

#include <stdio.h>

#include <sqlite3.h>


int main()

{

int ret = -1;

int row,column,i;

sqlite3 * db = NULL;//定义一个数据库连接对象指针

char * errmsg = NULL;

char **result = NULL;

ret = sqlite3_open("1.db",&db);

if(ret == SQLITE_OK)

{

printf("open db success!!\n");

}

else

{

fprintf(stderr,"failure %S \n",sqlite3_errmsg(db));//获取连接对象的错误信息

return -1;

}

char *sql = "insert into test_table values("liman","female","18");"//插入表操作

ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);

if(ret != SQLITE_OK)

{

fprintf(stderr,"failure %S \n",errmsg);//获取连接对象的错误信息

return -1;

}

char *sql ="select * from test_table;";

//获取结果集

ret = sqlite3_get_table(db,sql,&result,&row,&column,&errmsg);

if(ret == SQLITE_OK)

{

for(i=1;i<(row+1)*column;i++)

printf("%s |",result[i]);

printf("\n");

}

else

{

fprintf(stderr,"get data failure %S \n",sqlite3_errmsg(db));//获取连接对象的错误信息

return -1;

}

sqlite3_free_table(result);

sqlite3_close(db);

return 0;

}

(7)把SQL语句编译成字节码,结合SQLite中相关的函数可以很大程度提高效率

SQLITE_API int sqlite3_prepare(

  sqlite3 *db,            /* 打开的数据库句柄 */

  const char *zSql,       /* SQL 表达式, UTF-8 编码 */

  int nByte,              /*  zSql 最大多少个字节. */

  sqlite3_stmt **ppStmt,  /* OUT: 处理后的表达式的句柄 */

  const char **pzTail     /* OUT: 指向zSql中未使用的部分 */

);

(8)一步步执行SQL语句字节码

SQLITE_API int sqlite3_step(sqlite3_stmt*);


(9)删除sqlite3_prepare生成的字节码

SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);


(10)在实际操作中经常使用约束变量来构造SQL字符串,进而执行插入、查询或者删除等操作。下面几个函数用来改变字节码中的约束变量:

SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);

SQLITE_API int sqlite3_bind_int(

sqlite3_stmt*, //编译后的字节码

int, //约束变量的index

int);//约束变量赋的值

SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);

SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);

SQLITE_API int sqlite3_bind_text(

sqlite3_stmt*,//编译后的字节码

 int,//约束变量的index

 const char*, //约束变量赋的字符串

 int n,//第三个参数中需要传递的长度,-1表示传递全部字符串

 void(*)(void*));//回调函数,比如执行完操作后做一些内存释放处理等工作

SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));

SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);

SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);

比如;sqlite3_bind_int(ppstmt,1,23);这句代码是更改字节码中第一个整形约束变量的值为23

(11)重置调用 sqlite3_bind_*修改的字节码。这样可以进一步重新给约束变量赋值

SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);


例3:向数据库中插入一条记录:

#include <stdio.h>

#include <sqlite3.h>


int main()

{

int ret = -1;

sqlite3 * db = NULL;//定义一个数据库连接对象指针

sqlites_stmt *stmt;

ret = sqlite3_open("1.db",&db);

if(ret == SQLITE_OK)

{

printf("open db success!!\n");

}

else

{

fprintf(stderr,"failure %S \n",sqlite3_errmsg(db));//获取连接对象的错误信息

return -1;

}

char *sql = "insert into test_table (name,sex,age) values(?,?,?)"//插入表操作

ret = sqlite3_prepare(db,sql,-1,&stmt,0);//把SQL语句编译成字节码

if(ret != SQLITE_OK)

{

fprintf(stderr,"failure %S \n",errmsg);//获取连接对象的错误信息

return -1;

}

sqlites_bind_test(stmt,1,"liyan",strlen("liyan"),NULL);//给约束变量绑定具体的内容

sqlites_bind_test(stmt,2,"female",strlen("female"),NULL);//给约束变量绑定具体的内容

sqlites_bind_int(stmt,3,18);

sqlites_step(stmt);//执行SQL命令

sqlites_finalize(stmt);//删除字节码

sqlite3_close(db);//关闭数据库

return 0;

}


以上是关于嵌入式工程师必知:SQLite数据库的主要内容,如果未能解决你的问题,请参考以下文章

工具开源的嵌入式数据库引擎: SQLite 3.8.7版本发布

Android开发工程师文集-1 小时学会SQLite

(26)SQLite集成与用法

分享吧嵌入式数据库 H2 Database vs SQLite

案例分享——健康管理APP(全套解决方案:蓝牙数采SQLite数据存储数据分析与服务器HTTP通信等可视化图形界面数据展示)

案例分享——健康管理APP(全套解决方案:蓝牙数采SQLite数据存储数据分析与服务器HTTP通信等可视化图形界面数据展示)