sqlite3 存储和查找二进制数据对象 使用c语言接口
思路:通过让代码执行执行sql语句进行查找,但二进制的显示方法无法确定所以,二进制数据对象查询语句略有不同。
注意:sqlite3的数据库以及开发环境不在本片介绍之中
- sqlite 支持存储blob(二进制大数据)
- 认识两个对象:sqlite3 * 数据库对象。
sqlite3_stmt* 语句执行对象;
- 使用c语言调用涉及函数接口
int sqlite3_open(const char * filename,sqlite3 **ppDb);- 功能打开或则创建一个sqlite数据库对象
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
//函数功能:打开或则创建一个sqlite数据库对象。数据库对象路径(包含名称),为第一个变量filename,
//第二个变量用于指向打开的数据库,它是一个sqlite3* 指针的地址。
// 返回值; 正确返回 SQLITE_OK宏,错误返回对应的错误码,可以使用 const char* sqlite_errmsg(sqlite3*);获取错误信息
-
SQLITE_API int sqlite3_close(sqlite3*);- 功能:关闭 sqlit3_open()打开的数据库。 传数据库指针就可以了
-
SQLITE_API int sqlite3_exec(sqlite3 *, const char *sql, int (*callback)(void *, int, char **, char **), void *, char **errmsg);- 功能:执行sql语句,若sql语句有返回数据,则每一行返回值调用一次处理函数,也就是callback回调函数。
-
SQLITE_API int sqlite3_exec( sqlite3*, /* An open database 数据库指针 */ const char *sql, /* SQL to be evaluated 待执行的sql语句 */ int (*callback)(void*,int,char**,char**), /* Callback function 回调函数指针,放回调函数 */ void *, /* 1st argument to callback 这个参数 是传给回调函数的,是回调函数中的第一个参数 */ char **errmsg /* Error msg written here 错误信息存放地址,需传入一个开辟了空间的指针地址,用于存放错误信息,若为NULL则自动开辟空间存放 */ ); -
下面函数功能,将SQL文本编译为字节代码,它将完成查询或更新数据库的工作。是sqlite3_stmt的构造函数
SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle 数据库 */
const char *zSql, /* SQL statement, UTF-8 encoded sql语句 */
int nByte, /* Maximum length of zSql in bytes. 语句长度 */
sqlite3_stmt **ppStmt, /* OUT: Statement handle 语句对象地址 */
const char **pzTail /* OUT: Pointer to unused portion of zSql 语句长度不足时存放于此,若语句长度够长这个可以为NULL */
);
-
SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));- 功能为sql语句中的?绑定数据,由于sql语句中你不能直接写序存储的二进制,所以语句中待存储的二进制位置使用?代替,然后用该函数为?指定数据。
-
SQLITE_API int sqlite3_bind_blob( sqlite3_stmt*, //由sqlite3_prepare 返回的语句对象 int, //第几个?号,由1开始编号 const void*, //存储目标的地址 int n, //目标的字节数 void(*)(void*)//释放函数,发生错误时调用这个错误释放储存目标,有几个特殊值, //SQLITE_STATIC,则SQLite假定该信息位于静态非托管空间中,不需要释放。 //如果值是SQLITE_TRANSIENT,则SQLite会在sqlite3_bind _ *()例程返回之前立即创建其自己的数据私有副本,一般使用SQLITE_TRANSIENT ); -
SQLITE_API int sqlite3_step(sqlite3_stmt*);- 功能:该例程用于评估先前由sqlite3_prepare()接口创建的预准备语句。对该语句进行评估,直到结果的第一行可用为止。要前进到结果的第二行,请再次调用sqlite3_step()。继续调用sqlite3_step()直到语句完成。不返回结果的语句(例如INSERT,UPDATE或DELETE语句)在单次调用sqlite3_step()时便运行完毕。
-
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);- 功能:释放语句对象。
案例code
/*
* @Author: spring
* @version:
* @Date: 2022-07-21 17:30:35
* @LastEditors: spring
* @LastEditTime: 2022-07-21 19:11:32
* @Descripttion:
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
typedef struct _One
{
int a;
int arr[10];
} One;
int main(int argc, char const *argv[])
{
sqlite3 *db;
sqlite3_stmt *stmt, *stmt1;
if (sqlite3_open("test.db", &db) != SQLITE_OK)
puts(sqlite3_errmsg(db));
char sql[128] = {0};
sprintf(sql, "create table test(id text,data blob);");
sqlite3_exec(db, sql, NULL, NULL, NULL);
// 插入数据
sprintf(sql, "insert into test values(?,?);");
if (sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL) != SQLITE_OK)
puts(sqlite3_errmsg(db));
One one = {.a = 12, .arr = {1, 2, 3, 4, 5, 6}};
// 需指定两个?的数据地址后运行
if (sqlite3_bind_text(stmt, 1, "123456", strlen("123456"), SQLITE_TRANSIENT) != SQLITE_OK)
puts(sqlite3_errmsg(db));
if (sqlite3_bind_blob(stmt, 2, &one, sizeof(One), SQLITE_TRANSIENT) != SQLITE_OK)
puts(sqlite3_errmsg(db));
// 执行 插入 一次只执行一次插入
sqlite3_step(stmt);
// 获取数据
sprintf(sql, "select id,data from test;");
if (sqlite3_prepare(db, sql, strlen(sql), &stmt1, NULL) != SQLITE_OK)
puts(sqlite3_errmsg(db));
//一次只获取一行
sqlite3_step(stmt1);
// 获取返回结果的列数,
int col_num = sqlite3_column_count(stmt1);
printf("col_num is %d\n", col_num);
// 获取对应列的返回值;
const char *id;
One *two;
id = (const char *)sqlite3_column_text(stmt1, 0);
two = (One *)sqlite3_column_blob(stmt1, 1);
printf("id is: %s\n", id);
printf("two a is: %d\n", two->a);
printf("two arr is:");
for (int i = 0; i < 10; i++)
{
printf("%d\t", two->arr[i]);
}
printf("\n");
sqlite3_finalize(stmt);
sqlite3_finalize(stmt1);
sqlite3_close(db);
return 0;
}
执行结果;

参考:https://www.sqlite.net.cn/cintro.html





