• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • SQLite學習筆記(八)-- BLOB數據的插入與查詢(C++實現)

    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++實現)

    版權聲明:本文為u014337397原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/u014337397/article/details/80603510

    智能推薦

    sqlite庫學習(5)sqlite插入

    創建數據庫和表 準備工作  (1)使用sqlite3_exec     (2)使用sqlite3_prepare_v2  ...

    c++學習筆記八(模板)

    非類型形參 如果類模板的成員函數在模板外實現,通常也需要寫在頭文件中,而不是寫在源文件中 特化(對號入座相應的模板)示例: 示例:...

    python學習筆記八:文件與目錄

    一、文件的打開和創建 1、打開 open(file,mode): file(file,mode): mode可取值: 2、創建 用w/w+/a/a+模式打開即可。 二、文件的讀取 1、String = FileObject.read([size]) or: 2、String = FileObject.readline([size]) 或者可以用next 3、List = FileObject.re...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    猜你喜歡

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    精品国产乱码久久久久久蜜桃不卡