SQLite学习笔记(八)-- BLOB数据的插入与查询(C++实现)

    科技2025-07-17  9

    1.什么是BLOB数据

    BLOB (binary large object)即二进制大对象,是一种可以存储二进制文件的容器。在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。常见的BLOB文件有图片、声音和自定义对象等。

    2.BLOB操作相关API介绍

    2.1 准备SQL语句

     

    2.2 BLOB绑定函数

     

     

    2.3 准备语句执行函数

     

     

    2.5 获取指定字段的整形数据值

     

     

    2.7 获取指定BLOB数据长度

     

     

    3.代码实例

     

    函数原型 int sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); 参数列表 sqlite3 *db —- 数据库操作句柄,由sqlite3_open()函数得到 const char *zSql —- SQL语句 int nByte —- sql语句的长度 sqlite3_stmt **ppStmt —- 编译好的准备语句指针,该指针可以由sqlite3_step()执行;如果函数发生错误,该指针为NULL const char **pzTail —- 当生成的指定语句超过nByte指定的长度时,剩余的语句存放位置。建议zSql和nByte设置足够长,这样该参数就可以直接置为NULL返回值 int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码函数原型 int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));   参数列表 sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 int —- 要绑定的BLOB下标,从1开始 const void* —- BLOB数据的指针 int n —- BLOB数据长度 void()(void) —- 析构回调函数,一般默认为空返回值 int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码函数原型 int sqlite3_step(sqlite3_stmt*);   参数列表sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到返回值 int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码函数原型 int sqlite3_column_int(sqlite3_stmt*, int iCol); 参数列表 sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 int iCol —- 列的编号,从0开始返回值 int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码

    2.6 获取指定字段的BLOB值

    函数原型 const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 参数列表 sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 int iCol —- 列的编号,从0开始返回值 const void * —- BLOB数据指针函数原型 int sqlite3_column_bytes(sqlite3_stmt*, int iCol); 参数列表 sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 int iCol —- BLOB下标,从1开始返回值 int —- BLOB数据长度代码说明 本例主要演示如何插入和查询自定义对象。测试平台 1.开发语言:C++ 2.开发工具:VS2015 3.操作系统:Win7 X64

    测试数据说明 测试表为Student_Blob表,其基本结构如下:

    #include <iostream> #include <Windows.h> using namespace std; //sqlite3头文件 #include "sqlite3.h" //sqlite3库文件 #pragma comment(lib,"sqlite3.lib") //函数功能:将utf8字符转gb2312字符 //参数: const char* utf8[IN] -- UTF8字符 //返回值: char* -- gb2312字符 char* U2G(const char* utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; return str; } //unicode字符转utf8 //函数功能:将gb2312字符转换为utf8字符 //参数: const char* gb2312[IN] -- gb2312字符 //返回值: char* -- UTF8字符 char* G2U(const char* gb2312) { int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; return str; } //测试学生数据结构体 typedef struct TestStudent { char name[20]; //姓名 int age; //年龄 }; //函数功能:向表中插入BLOB数据 //参数: sqlite3 *db[IN] -- 数据库操作指针 // const TestInfoStruct* info[IN] -- 要插入的信息 // const int recordId[IN] -- 记录ID //返回值: bool -- 函数执行成功,则返回true;否则返回false bool InsertBlobData(sqlite3 *db, const TestStudent student,const int recordId) { char *zErrMsg = 0; char sql[1000]; int rc; sqlite3_stmt *stmt; sprintf_s(sql, "insert into Student_Blob values('%d',?);", recordId); sqlite3_prepare(db, sql, strlen(sql), &stmt, 0); { sqlite3_bind_blob(stmt, 1, &student, sizeof(TestStudent), NULL); sqlite3_step(stmt); } sqlite3_finalize(stmt); return true; } //函数功能:向表中插入BLOB数据 //参数: sqlite3 *db[IN] -- 数据库操作指针 // TestInfoStruct* info[IN] -- 要插入的信息 //返回值: bool -- 函数执行成功,则返回true;否则返回false bool SelectBlobData(sqlite3 *db) { char *zErrMsg = 0; char sql[1000]; int rc; sqlite3_stmt *stmt; //读取数据 sqlite3_prepare(db, "select * from Student_Blob;", strlen("select * from Student_Blob;"), &stmt, 0); int result = sqlite3_step(stmt); int id = 0, len = 0; while (result == SQLITE_ROW) { char cStudentId[20]; TestStudent tempStudent; cout << endl<<"查询到一条记录" << endl; id= sqlite3_column_int(stmt, 0); cout << "记录编号:" << id << endl; const void * pReadBolbData = sqlite3_column_blob(stmt, 1); len = sqlite3_column_bytes(stmt, 1); memcpy(&tempStudent, pReadBolbData, len); cout << "姓名=" << tempStudent.name << endl; cout << "年龄=" << tempStudent.age << endl; result = sqlite3_step(stmt); } sqlite3_finalize(stmt); return true; } int main() { //操作数据库 sqlite3 *db; char *zErrMsg = 0; char sql[1000]; sqlite3 *pDataBase = NULL; //打开数据库 //如果路径不含中文,可以不用转码。不过保险起见,建议全部转码。 int iRet = sqlite3_open(G2U("E:\\sqlite数据库\\testSQLite.db"), &pDataBase); if (iRet) { cout << "数据库打开失败,失败原因:" << sqlite3_errmsg(pDataBase) << endl; } else { cout << "数据库打开成功!" << endl; //写BLOB数据 TestStudent student1; sprintf_s(student1.name, "张三"); student1.age = 19; InsertBlobData(pDataBase,student1,1); TestStudent student2; sprintf_s(student2.name, "李四"); student2.age = 18; InsertBlobData(pDataBase, student2,2); //读取数据 SelectBlobData(pDataBase); //关闭数据库 iRet = sqlite3_close(pDataBase); if (0 == iRet) { cout << "数据库关闭成功!" << endl; } } getchar(); return 0; }

    输出结果

    Processed: 0.012, SQL: 8