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++實現)
智能推薦
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...
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 以上述例子,判斷一個生產出...