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

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;
    }
  • 输出结果

©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页