sqlite3_stmt*数据类型使用介绍
sqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt *。
这个数据类型 记录了一个“sql语句”。为什么我把 “sql语句” 用双引号引起来?因为你可以把 sqlite3_stmt *所表示的内容看成是sql语句,但是实际上它不是我们所熟知的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。
正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到 sqlite3_stmt 结构里可不能直接memcpy ,也不能像 std::string 那样用 + 号。必须用 sqlite 提供的函数来插入。8 e( q3 j! b%j f
1 o1 g:v& o& b8 s%_ s. h- `
: y' z5y& s; h! w
i.1
写入二进制
下面说写二进制的步骤。' l5 d$ v/ z' h' e:w
+ n' a' r9e* t3 i$ 0 p' | ]
要插入二进制,前提是这个表的字段的类型是 blob 类型。我假设有这么一张表:复制内容到剪贴板
代码:
create table tbl_2( id integer,file_content blob)首先声明
# [2 m. s![( n; @1 v
sqlite3_stmt * stat;
- u7 z# h#b h% p0 @6 e2 v; b
然后,把一个 sql 语句解析到 stat 结构里去:复制内容到剪贴板
代码:
sqlite3_prepare( db, “insert into tbl_2( id, file_content)values( 10, )”, -1, &stat, 0 );上面的函数完成 sql 语句的解析。第一个参数跟前面一样,是个 sqlite3 * 类型变量,第二个参数是一个 sql语句。
这个 sql 语句特别之处在于 values 里面有个 号。在sqlite3_prepare函数里,号表示一个未定的值,它的值等下才插入。
第三个参数我写的是-1,这个参数含义是前面 sql语句的长度。如果小于0,sqlite会自动计算它的长度(把sql语句当成以\0结尾的字符串)。8 w# |5 u0 ~8 }. z' e,a
* u/ f5 c"v: l7 x4 n. }2 h3 k
第四个参数是 sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。+ f6 n! b;d& , n
- {# e* e:o7 f# t
第五个参数我也不知道是干什么的。为0就可以了。
如果这个函数执行成功(返回值是 sqlite_ok 且 stat 不为null ),那么下面就可以开始插入二进制数据。复制内容到剪贴板
代码:
sqlite3_bind_blob( stat, 1, pdata,(int)(length_of_data_in_bytes), null ); //pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位这个函数一共有5个参数。
第1个参数:是前面prepare得到的 sqlite3_stmt * 类型变量。
第2个参数:号的索引。前面 prepare的sql语句里有一个号,假如有多个号怎么插入?方法就是改变 bind_blob函数第2个参数。这个参数我写1,表示这里插入的值要替换 stat的第一个号(这里的索引从1开始计数,而非从0开始)。如果你有多个号,就写多个 bind_blob语句,并改变它们的第2个参数就替换到不同的号。如果有号没有替换,sqlite为它取值null。4 |+ q5 l) k, a;_
第3个参数:二进制数据起始指针。" w, n4 i: q, l; h$ o,^; x2 ^
5 w* i* ^6i4 z p7 }
第4个参数:二进制数据的长度,以字节为单位。
0 c+f& y6 }' f0 v0 g5 k/ h
第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填null,需要释放的内存自己用代码来释放。
bind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到里:复制内容到剪贴板
代码:
int result = sqlite3_step( stat );通过这个语句,stat 表示的sql语句就被写到了数据库里。
" @3 u0 x*h2 r: s+ e3 a
最后,要把 sqlite3_stmt 结构给释放:复制内容到剪贴板
代码:
sqlite3_finalize( stat ); //把刚才分配的内容析构掉i.2 读出二进制& q+{% f9 i8 j8 n+ s g4 l: s.q
下面说读二进制的步骤。
4 c, i8 [5}: d5 o
跟前面一样,先声明 sqlite3_stmt * 类型变量:复制内容到剪贴板
代码:
sqlite3_stmt * stat;然后,把一个 sql 语句解析到 stat 结构里去:复制内容到剪贴板
代码:
sqlite3_prepare( db, “select * from tbl_2”, -1,&stat, 0 );当 prepare 成功之后(返回值是 sqlite_ok ),开始查询数据。复制内容到剪贴板
代码:
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 是二进制,因此我需要得到它的指针,还有它的长度:复制内容到剪贴板
代码:
const void * pfilecontent =sqlite3_column_blob( stat, 1 );
int len =sqlite3_column_bytes( stat, 1 );这样就得到了二进制的值。& 6^, }3 p2 h# o4 [! m5 a2 x
把 pfilecontent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:复制内容到剪贴板
代码:
sqlite3_finalize( stat ); //把刚才分配的内容析构掉i.3 重复使用 sqlite3_stmt 结构
如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数:sqlite3_reset。复制内容到剪贴板
代码:
result = sqlite3_reset(stat);这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。
上一篇: SQLite5个APIs的概述及实例讲解