SQLITE3 使用总结(四)

2)读出二进制

下面说读二进制的步骤。
跟前面一样,先声明 sqlite3_stmt * 类型变量:

?
1
sqlite3_stmt * stat;

然后,把一个 sql 语句解析到 stat 结构里去:

?
1
sqlite3_prepare( db, “select * from Tbl_2”, -1, &stat, 0 );

当 prepare 成功之后(返回值是 SQLITE_OK ),开始查询数据。

?
1
int result = sqlite3_step( stat );

这一句的返回值是SQLITE_ROW 时表示成功(不是 SQLITE_OK )。
你可以循环执行sqlite3_step 函数,一次step查询出一条记录。直到返回值不为 SQLITE_ROW 时表示查询结束。
然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:
int id = sqlite3_column_int( stat, 0 ); //第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字段是第一个字段,因此这里我填0
 
下面开始获取 file_content 的值,因为 file_content 是二进制,因此我需要得到它的指针,还有它的长度:

?
1
2
const void * pFileContent = sqlite3_column_blob( stat, 1 );
int len = sqlite3_column_bytes( stat, 1 );

这样就得到了二进制的值。
把 pFileContent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:
sqlite3_finalize( stat ); //把刚才分配的内容析构掉
 
(3)重复使用 sqlite3_stmt 结构

如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数: sqlite3_reset。

?
1
result = sqlite3_reset(stat);

这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。

4 事务处理

sqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。
通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。
你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。

事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:
分别如下:

?
1
2
3
4
int result;
result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //开始一个事务
result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事务
result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //回滚事务

四、C/C++开发接口简介1 总览

SQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:
支持UTF-16编码.
用户自定义的文本排序方法.
可以对BLOBs字段建立索引.
因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0版. 至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.
3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意. 所有API接口函数和数据结构的前缀都由"sqlite_"改为了"sqlite3_". 这是为了避免同时使用SQLite 2.X和SQLite 3.0这两个版本的时候发生链接冲突.
由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范. 因此SQLite使用了普通的void* 类型来指向UTF-16编码的字符串. 客户端使用过程中可以把void*映射成适合他们的系统的任何数据类型.

2 C/C++接口
SQLite 3.0一共有83个API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open(), sqlite3_exec(), 和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.

(1)如何打开关闭数据库
 

?
1
2
3
4
5
6
7
typedef struct sqlite3 sqlite3;
  int sqlite3_open(const char*, sqlite3**);
  int sqlite3_open16(const void*, sqlite3**);
  int sqlite3_close(sqlite3*);
  const char *sqlite3_errmsg(sqlite3*);
  const void *sqlite3_errmsg16(sqlite3*);
  int sqlite3_errcode(sqlite3*);

sqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open() 和sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名. 如果要创建新数据库, sqlite3_open16() 将内部文本转换为UTF-16编码, 反之sqlite3_open() 将文本转换为UTF-8编码.
打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行. 而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.
sqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明. 这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16() 和sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.
SQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define SQLITE_OK      0  /* Successful result */
#define SQLITE_ERROR    1  /* SQL error or missing database */
#define SQLITE_INTERNAL   2  /* An internal logic error in SQLite */
#define SQLITE_PERM     3  /* Access permission denied */
#define SQLITE_ABORT    4  /* Callback routine requested an abort */
#define SQLITE_BUSY     5  /* The database file is locked */
#define SQLITE_LOCKED    6  /* A table in the database is locked */
#define SQLITE_NOMEM    7  /* A malloc() failed */
#define SQLITE_READONLY   8  /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT  9  /* Operation terminated by sqlite_interrupt() */
#define SQLITE_IOERR    10  /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT   11  /* The database disk image is malformed */
#define SQLITE_NOTFOUND  12  /* (Internal Only) Table or record not found */
#define SQLITE_FULL    13  /* Insertion failed because database is full */
#define SQLITE_CANTOPEN  14  /* Unable to open the database file */
#define SQLITE_PROTOCOL  15  /* Database lock protocol error */
#define SQLITE_EMPTY    16  /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA   17  /* The database schema changed */
#define SQLITE_TOOBIG   18  /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT 19  /* Abort due to contraint violation */
#define SQLITE_MISMATCH  20  /* Data type mismatch */
#define SQLITE_MISUSE   21  /* Library used incorrectly */
#define SQLITE_NOLFS    22  /* Uses OS features not supported on host */
#define SQLITE_AUTH    23  /* Authorization denied */
#define SQLITE_ROW     100 /* sqlite_step() has another row ready */
#define SQLITE_DONE    101 /* sqlite_step() has finished executing */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值