嵌入式数据库SQLite3相关操作---数据库移植篇

准备工作:

主机环境:虚拟机下Fedora9

交叉编译器:arm-linux-gcc-4.4.3

软件包:sqlite-3.6.18.tar.bz2

把sqlite-3.6.18.tar.bz2解压到主机的/nfs_dir/目录下,并重命名为sqlite,在同一级目录下在新建目录sqlite_arm,这个目录来放编译后产生的文件。

二.配置SQLite

在sqlite目录终端下进行如下配置:

./configure --prefix=/nfs/sqlite/sqlite_arm --disable-tcl --host=arm-linux

make

make install

经 过上述的命令将编译好的文件安装到sqlite-arm目录下,在sqlite-arm目录下会生成bin、lib、include目录,bin目录下是 sqlite3可执行文件,lib目录下包含运行sqlite3所依赖的库,include目录下是sqlite的C语言API的头文件,编程时会用到。

三.移植

分别将bin下的文件下载到开发板的/usr/bin目录中,lib下的所有文件下载到开发板的/usr/lib目录中即可。注意这里说的是所有。包括符号连接,即一个不留:

cp –dr ./lib/ /usr/lib/

四.登录开发板的Linux,执行:

sqlite3 demo.db

sqlite3是一个sqlite的命令行访问程序,demo.db是新建的数据库的名字,必须以db作后缀。如果能进行下边的操作说明一切OK.

#sqlite3 test.db
SQLite version 3.6.18
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table film (number,name);
sqlite> insert into film values (1,'aaa');
sqlite> insert into film values (2,'bbb');
sqlite> select * from film;
1|aaa
2|bbb
sqlite>.quit

五.测试程序

这里以SQLite官方站点http://sqlite.org的quick start文档中的测试程序为例对移植到ARM-Linux上的SQLite3进行测试。该程序清单如下:

#include <stdio.h>

#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName)

{

    int i;

    for(i=0; i<argc; i++){

         printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");

    }

    printf("\n");

    return 0;

}

int main(int argc, char **argv)

{

    sqlite3 *db;

    char *zErrMsg = 0;

    int rc;

    if( argc!=3 ){

         fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);

    }

    rc = sqlite3_open(argv[1], &db);

    if( rc ){

         fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));

         sqlite3_close(db);

    }

    rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);

    if( rc!=SQLITE_OK ){

         fprintf(stderr, "SQL error: %s\n", zErrMsg);

    }

    sqlite3_close(db);

    return 0;

}

使用如下命令编译测试程序:

arm-linux-gcc -o test test.c -lsqlite3 -L/nfs/sqlite/sqlite_arm/lib -I/nfs/sqlite/sqlite_arm/include

使用如下命令去掉调试信息:

arm-linux-strip test

六.在上面新建的数据库目录下测试:
#./test_sqlite   test.db   "select * from film"  

应该会看到如下的结果:
number = 1
name = aaa
number = 2
name = bbb

好 了,挺简单的吧,sqlite也是一个关系性数据库,可以做的其实也是比较少的,或者说要学的新东西还是挺少的,以前的数据库连oracle,DB2都玩 的转,何况这个小家伙,塞牙缝都不够啊.下节我们会讲讲sqlite3中的一些基本的编程接口,有了这些接口,C编程问题还不是手到擒来啊.

嵌入式数据库SQLite3相关操作---操作接口篇

在上节中,我们介绍了有关SQLite3移植到开发板的过程,这节就大家总结了一下SQLite3提供的C语言编程接口,以供大家编程时使用方便。

首先要说明的是。sqlite3本身是提供了一些命令来操作数据库的。为了与SQL语句相区别,他们都是以小数点.开头。可以用

.help  获取相关命令

一,打开和关闭数据库

使用SQLite3接口操作数据库时都要先打开数据库,有点多余啊,哪个数据库不是呢?嘿嘿

int sqlite3_open(const char *filename, sqlite3 **ppDb);

参数即返回值意义如下:

filename:要打开的数据库的文件名

ppDb:用户返回数据库句柄

返回值:SQLITE_OK代表成功,否则为错误码

其实返回的错误码可以在SQLite3源码的sqlite3.h头文件找到,这里就不说了。需要说明的是这些错误是SQLite3编程接口共同使用的。而不是sqlite3_open函数私有。

用完了,当然要关闭:

int sqlite3_close(sqlite3 *ppDb);

二,执行SQL语句

SQLite3提供了一个一般化的编程接口,可以对以打开的数据库执行任何SQL语句。这个函数的原型如下:

int sqlite3_exec(sqlite3 *pDb, const char *sql,
                          int (*callback)(void* context, int nArg, char** azArg, char** azCol),
                          void *context, char **errmsg);

参数即返回值意义如下:

pDb:已打开的数据库的句柄

sql:字符串,内容是一条或多条sql语句

callback:回调函数

context:传递给回调函数的第一个参数,可称上下文参数

errmsg:指向一个字符串,其内容是对操作中发生的错误的文字描述

返回值:SQLITE_OK代表成功,否则为错误码

回调函数的作用是:当进行查询操作时,每查询到一条记录都会调用一次回调函数,这条记录的内容通过回调函数的参数传入。回调函数的参数既返回值的含义解释如下:

context:调用sqlite3_exec时传入的context指针。

nArg:数据的个数

azArg:字符串数组,有nArg个元素,表示每个字段的值

azCol:字符串数组,有nArg个元素,表示每个字段的名称

返回值:0表示要继续查询否则查询操作结束,对sqllite3_exe函数的调用将返回错误码SQLITE_ABORT.

即使记录中某个字段的类型为整数,它的值也是由C语言的字符串来代表中。

还 有就是errmsg参数是一个字符指针变量的地址,通过它将得到一个字符串的首地址。显然,这个字符串的存储空间是在sqlite3_exec函数内动态 分配得到的,因此用过后必须释放以免造成内存泄漏。鉴于外界并不知道sqlite3_exe函数内部是如何进行内存分配的。SQLite3平台专门提供了 一个函数用于释放这块内存,其原型如下:

void sqlite3_free(void *p);

其中参数P指向要释放的内存。

三.查询数据库

其实呢,使用上面的sqlite3_exec函数就可以对数据库进行查询操作,但它使用回调函数作为返回结果的手段,有时不是很方便,因此SQLite3也提供了一个专门的接口进行查询操作,其函数原型如下:

sqlite3_get_table(sqlite3 *pDb, const char *sql, char ***pResult, int *nrow, int *ncolumn, char **errmsg);

其中各个参数的含义解释如下:

pDb:已打开的数据库的实例

sql:字符串,内容是一条或多条SQL语句。

pResult:一个(char **)型变量的地址,用于返回查询结果,查询结果由字符串数组代表。

nrow:结果表的行数。

ncolumn:结果的列数

errmsg:指向一个字符串,其内容是对操作中发生的错误的文字描述

这 里的参数都好理解,不好理解的是pResult是查询的结果,它是一个字符串数组,因此它的首地址是(char **)地址。虽然它是一个一维的字符串数组,但要以二维的方式去理解,其中前ncolumn个字符串表示结果表的字段名,随后的ncolumn个字符串则 是第一条记录的各个字段的值,依次类推。

内外一个需要说明的问题就是空间的问题,显然pResult所指向的字符串数组及各个字符串所占 的空间都是在sqlite3_get_table函数内部动态分配得到的。因此需要使用后进行释放。由于它又不是一块平坦的内存,故也不能用 sqlite3_free函数来释放,而必须用下面这个专用的函数:

void sqlite3_free_table(char **result);
其中,result参数就是查询得到的结果表的首地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值