博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于C API的SQLite3基本数据库操作
阅读量:5828 次
发布时间:2019-06-18

本文共 5470 字,大约阅读时间需要 18 分钟。

SQLite是一款开源嵌入式文件型数据库,这个主要是和其他一些C/S架构的关系型数据库比较而来的,比如MySQL等。

说他是嵌入式,因为SQLite的所有功能全部包装在一个dll中,我们只需要使用其中的导出接口就可以操作SQLite数据库,这样使得数据存储功能能够很方便的集成进用户的程序中,并运行在客户程序的进程空间中

说他是文件型,因为SQLite的数据库文件就是一个独立文件(SQLite本身不限制数据库文件的扩展名),再没有其他的了,数据,表结构,查询,视图等等都保存在这个数据库文件中,不会依赖任何数据库环境

SQLite的主要特点:
1。无需部署,0配置,无服务端
2。跨平台
2。数据文件管理方便
3。较完善的SQL92标准支持,SQLite基本实现了SQL92标准,其他的一些不兼容的地方,可以参看官方相关说明,链接:
4。SQL语句执行速度快,具体的对比数据,网上的评测有很多,这里就不多说了
5。应用较广。最著名的集成应该数Android了吧,其他的PHP ,Python等都做了集成,所以还是很不错的
6。完美的Unicode编码支持。SQLite的接口中,凡是涉及字符串的都是用UTF8或UTF16编码交互,有的同时提供这两种编码的接口函数,所以多语种支持绝对不是问题(这也是我偏爱SQLite的很重要的原因,呵呵)。

好了,下面说说基于C API的SQLite操作,这里谢绝讨论其他的一些包装库,这不是本文的范围,当然SQLite的接口包装库函数还是很多的,基本覆盖各种主流开发语言。如基于Object Pascal的sqlitesimpledelphi,想了解这个库的朋友可以查看我的其他博文:

Delphi 2010下使用sqlitesimpledelphi连接SQLite数据库及中文乱码问题的解决
sqlitesimpledelphi修正以支持Unicode,Delphi 2010 测试通过
SQLite的数据库操作其实和常规的数据库操作流程是一样的:
1。连接数据库。
2。构造SQL语句并执行
3。对于SELECT语句,可以获取查询结果
4。数据库使用完毕之后,关闭数据库

这里说明一下,下面所介绍的函数不会涵盖所有的API函数,毕竟SQLite针对同一个功能点提供了不同的API函数,主要表现在参数和配置功能上,有需要深入了解的朋友可以参考官方的文档。

1。打开数据库

API函数:
int sqlite3_open(
const char *filename,   /* 数据库文件路径(UTF-8编码) */
sqlite3 **ppDb          /* 输出: SQLite 数据库句柄 */
);
int sqlite3_open16(
const void *filename,   /* 数据库文件路径(UTF-16) */
sqlite3 **ppDb          /* 输出: SQLite 数据库句柄 */
);
如果调用成功会返回SQLITE_OK,否则返回错误码。

2。构造SQL语句,这里就不多说了,这和SQLite本身无关,可以根据需要使用适当的方法构造即可,注意传给SQLite函数的时候,字符串编码要记得转换为UTF8/UTF16

3。执行SQL语句。

在SQLite中执行SQL语句比较简单的方法是调用函数:
int sqlite3_exec(
sqlite3*,                                  /* 打开的数据库句柄 */
const char *sql,                           /* UTF8编码的SQL语句 */
int (*callback)(void*,int,char**,char**), /* 回调函数,对于SELECT语句返回的结果处理在回调函数中进行 */
void *,                                    /* 传递给回调函数的参数 */
char **errmsg                              /* 相关错误信息 */
);

其实sqlite3_exec只是封装了sqlite3_prepare、sqite3_step(即SQL中的预编译技术)的,主要目的是为使用者提供方便,笔者个人觉得使用后者会更加好一点,这里先做一下总结:

int sqlite3_prepare(

sqlite3 *db,            /* 打开的数据库句柄 */
const char *zSql,       /* UTF8编码的SQL语句,可以参数化 */
int nByte,              /* SQL语句的字节长度,可以传递-1,即字符串以\0结尾 */
sqlite3_stmt **ppStmt, /* 输出:预编译之后的SQL语句句柄 */
const char **pzTail     /* 输出: 指向zSql缓冲区中跳过有效SQL字符串的第一个字节 */
);

int sqlite3_prepare_v2(

sqlite3 *db,            /* 打开的数据库句柄 */
const char *zSql,       /* UTF8编码的SQL语句,可以参数化 */
int nByte,              /* SQL语句的字节长度,可以传递-1,即字符串以宽字符\0结尾 */
sqlite3_stmt **ppStmt, /* 输出: 预编译之后的SQL语句句柄 */
const char **pzTail     /* 输出: 指向zSql缓冲区中跳过有效SQL字符串的第一个字节 */
);

int sqlite3_prepare16(

sqlite3 *db,            /* 打开的数据库句柄 */
const void *zSql,       /* UTF16编码的SQL语句,可以参数化 */
int nByte,              /* SQL语句的字节长度,可以传递-1,即字符串以宽字符\0结尾 */
sqlite3_stmt **ppStmt, /* 输出: 预编译之后的SQL语句句柄 */
const void **pzTail     /* 输出: 指向zSql缓冲区中跳过有效SQL字符串的第一个字节 */
);

int sqlite3_prepare16_v2(

sqlite3 *db,            /* 打开的数据库句柄 */
const void *zSql,       /* UTF16编码的SQL语句,可以参数化 */
int nByte,              /* SQL语句的字节长度,可以传递-1,即字符串以宽字符\0结尾 */
sqlite3_stmt **ppStmt, /* 输出: 预编译之后的SQL语句句柄 */
const void **pzTail     /* 输出: 指向zSql缓冲区中跳过有效SQL字符串的第一个字节 */
);

其中带参数的SQL语句可以这样定义参数:

?NNN 
:VVV 
@VVV 
$VVV 
参数编号从1开始,例如:INSERT into db values(?1, ?2)

v2版本函数时SQLite根据需要添加的增强函数,新的程序推荐使用v2版本函数,只需与原来函数的区别,可以参考官方原文

int sqlite3_step(sqlite3_stmt*);

执行一次预编译SQL语句,在这之前,如果SQL是参数化的,可以调用sqlite3_bind来绑定数据,int、string、blob等等
如果执行成功会返回SQLITE_DONE,如果查询有结果会返回SQLITE_ROW,并可以通过API获取结果中的第一行数据,需要获取下一行数据可以再次调用sqlite3_step直到返回SQLITE_DONE表示后面没有数据了
如果需要重新对预编译的SQL绑定数据并执行,需要先reset一下,然后再调用step,即函数:
int sqlite3_reset(sqlite3_stmt *pStmt);

下面是绑定数据到预编译SQL语句的相关函数:

以下函数的第一个参数指代预编译的SQL句柄,第二个参数指代绑定的参数编号,对应于参数化的SQL语句中的参数编号:

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

该函数用于绑定二进制数据BLOB,其中最后一个参数是一个回调函数,当成功绑定数据后,会被调用,一般用于自动释放对应的缓冲区

int sqlite3_bind_double(sqlite3_stmt*, int, double);

该函数绑定double浮点数

int sqlite3_bind_int(sqlite3_stmt*, int, int);

该函数绑定int整数

int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);

该函数用于绑定具有64位长度的整数,对应于C中的long long结构,由于一个int的范围可能无法满足超大数据量的要求,所以SQLite也支持64位整数,毕竟SQLite官方声称SQLite是支持最大2T的数据的

int sqlite3_bind_null(sqlite3_stmt*, int);

该函数绑定一个空数据到指定列

int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));

该函数绑定一段字符串,源字符串是UTF8编码的

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

该函数绑定一段字符串,源字符串是UTF16编码的

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

该函数绑定以SQLite结构sqlite3_value存储的通用数据,其中sqlite3_value可以是上述的所有类型,此函数不太常用

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

该函数绑定指定大小的全零BLOB数据

3。获取SQL查询结果

对于SELECT语句,还需要能够获取结果。上面也提到调用sqlite3_step之后,对于有结果的查询会返回第一行结果,这时可以通过API函数获取当前行的指定字段结果:

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

该函数以BLOB数据格式获取对应列的数据,BOLB长度使用sqlite3_column_bytes获取

int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
该函数可以用于返回BLOB和字符串的字节长度。对于BLOB,两个函数效果是一样的,但是对于字符串sqlite3_column_bytes返回的是UTF8编码的字符串长度,而sqlite3_column_bytes16返回的是UTF16编码的字符串长度,其间会做必要的字符串格式转换

double sqlite3_column_double(sqlite3_stmt*, int iCol);

该函数返回double数据列

int sqlite3_column_int(sqlite3_stmt*, int iCol);

该函数返回int数据列

sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

该函数返回64位整数,即long long数据

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
该函数返回字符串,其中sqlite3_column_text输出的字符串使用UTF8编码

sqlite3_column_text16使用UTF16编码

int sqlite3_column_type(sqlite3_stmt*, int iCol);
该函数返回对应列的数据类型

sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

该函数以sqlite3_value结构体返回数据

上面是根据列ID来获取对应的列数据的,如果想通过列名称获取列数据,则需要将列名称转换为对应的列ID,可以使用下面的函数:

const char *sqlite3_column_name(sqlite3_stmt*, int N);
const void *sqlite3_column_name16(sqlite3_stmt*, int N);
该函数返回对应列的名称

4。关闭数据库

int sqlite3_close(sqlite3 * db);

使用该函数可以关闭数据库

好了,基本的调用流程就这么些了,看完这篇文章,应该能够完成基本的数据读写操作了,至于其他的高级操作,有兴趣的朋友可以登录SQLite官方网站查看,这里就不在本文多说了。

转载地址:http://rcodx.baihongyu.com/

你可能感兴趣的文章
AT&T和三星加入5GAA 进军联网汽车市场
查看>>
IT招聘市场最热门的五类开源技术人才
查看>>
网络安全法正式实施 云安全如何与时俱进?
查看>>
集成商、渠道商怎样开展视频会议项目
查看>>
环信PaaS+SaaS齐头并进,打造最具生命力企业服务
查看>>
【百度地图API】自行获取区域经纬度的工具
查看>>
事务的特点和隔离级别
查看>>
BLUEZ编程
查看>>
韩国三月_热心的韩国朋友
查看>>
maven - 下载jar包
查看>>
对象字段与json下划线字段的相互转换
查看>>
英语听力/口语网站
查看>>
php------数组函数
查看>>
openfire 3.8.1 的JDK陷阱
查看>>
nginx init.d script
查看>>
这是不是PHP的bug
查看>>
2011 IT公司笔试面试题目整理
查看>>
Nginx源码解析- http模块分析
查看>>
手机自动化测试:Appium源码分析之跟踪代码分析九 1
查看>>
GBin1分享:jQuery1.7 Beta 预览
查看>>