SQLite学习笔记(八)-- BLOB数据的插入与查询(C++实现)
1.什么是BLOB数据BLOB (binary large object)即二进制大对象,是一种可以存储二进制文件的容器。在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。常见的BLOB文件有图片、声音和自定义对象等。2.BLOB操作相关API介绍2.1 准备SQL语句函数原型int sqlite3_prepare(sqlite3 *db,...
·
1.什么是BLOB数据
BLOB (binary large object)即二进制大对象,是一种可以存储二进制文件的容器。在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。常见的BLOB文件有图片、声音和自定义对象等。
2.BLOB操作相关API介绍
2.1 准备SQL语句
- 函数原型
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;否则返回错误码
2.2 BLOB绑定函数
- 函数原型
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;否则返回错误码
2.3 准备语句执行函数
- 函数原型
int sqlite3_step(sqlite3_stmt*);
- 参数列表
sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 - 返回值
int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码
2.4 销毁准备语句函数
- 函数原型
int sqlite3_finalize(sqlite3_stmt *pStmt);
- 参数列表
sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到 - 返回值
int —- 函数执行成功时,返回SQLITE_OK;否则返回错误码
2.5 获取指定字段的整形数据值
- 函数原型
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数据指针
2.7 获取指定BLOB数据长度
- 函数原型
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
- 参数列表
sqlite3_stmt* —- 准备语句指针,该指针有sqlite3_prepare()函数得到
int iCol —- BLOB下标,从1开始 - 返回值
int —- BLOB数据长度
3.代码实例
- 代码说明
本例主要演示如何插入和查询自定义对象。 - 测试平台
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;
}
- 输出结果
栏目导航
上一篇:SQLite学习笔记(七)– 数据插入、更新和删除(C++实现)
下一篇:SQLite学习笔记(九)– 视图的定义与删除(C++实现)
更多推荐
已为社区贡献1条内容
所有评论(0)