嵌入式工程师必知: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版本发布
分享吧嵌入式数据库 H2 Database vs SQLite
案例分享——健康管理APP(全套解决方案:蓝牙数采SQLite数据存储数据分析与服务器HTTP通信等可视化图形界面数据展示)
案例分享——健康管理APP(全套解决方案:蓝牙数采SQLite数据存储数据分析与服务器HTTP通信等可视化图形界面数据展示)