有時我們用數據庫存儲文件,需要用到二進制字段,下面列常用方法。
1.寫二進制數據
sqlite3 * db;
int result;
char **errmsg =NULL;
result = sqlite3_open("test.db", &db );
if( result != SQLITE_OK )
{ return -1;}
result = sqlite3_exec( db,"create table tb( ID integer, content blob)", NULL, NULL, errmsg);
if(result != SQLITE_OK){printf("erro");}
char *buffer;//要寫的二進內容,也可以從文件讀出來
buffer=new char[1024*1024];
for(int i=0;i<1024*1024;i++)buffer[i]='a';
sqlite3_stmt *stat;//寫二進制數據時要用的結構
sqlite3_prepare( db, "insert into tb( ID, content) values( 10, ? )", -1, &stat, 0 );//准備插入數據
sqlite3_bind_blob( stat, 1, buffer, strlen(buffer), NULL ); //把內容和字段綁定
result=sqlite3_step( stat );//執行
sqlite3_finalize( stat );釋放內存
sqlite3_close( db );
2.讀二進制數據
這裡重點介紹一下sqlite3_blob_open函數
這個函數用於打開二進制字段數據
第一個參數是數據庫句柄
第二個參數是數據庫名
第三個參數是表名
第四個參數是二進制數據字段(列)名
第五個參數是行數,也就是打開第幾行的字段。
第六個參數是讀寫標志,0為讀,1為讀和寫
第七個參數是二進制文件句柄
用這個函數打二進制字段就像打開文件一樣簡單。
下面為例子代碼:
sqlite3 * db;
int result;
char **errmsg =NULL;
result = sqlite3_open("test.db", &db );
if( result != SQLITE_OK )
{ return -1;}
int rf= sqlite3_blob_open(db,NULL,"Tbl_2","file_content",1,1,&sqlite3_blob);
if(rf!= SQLITE_OK)return –1;
int len=sqlite3_blob_bytes(sqlite3_blob);//得到二進數據長度
sqlite3_blob_read(sqlite3_blob,buffer,len,0); 讀二進數據,最後一個參數為起始位置
//如果不想讀全部內容,可以設置這個參數
sqlite3_blob_close(sqlite3_blob);//關閉
sqlite3_close( db );
3.幾個問題
a. sqlite3_blob_open函數第五個參數讀第幾行的數據,不知道通過什麼函數能得到當前行的絕對行數,而sqlite3_total_changes函數只能得更改行的相對行數。
b. sqlite3_blob_write函數是用於寫二進制數據,但這個函數只能用於修改二進制數據,不能用於插入二進制數據,而寫數據的時候長度不能超過第一次插入數據時的長度。
我希望存儲的單個二進數據字段可能有幾個G的容量,而且隨時有可能修改,長度會不斷變化,用sqlite3_stmt顯然是不行的,而sqlite3_blob_write函數又不能改變二進數據字段的長度,是我對Sqlite了解的不多,還是這個數據庫本身就有這個限制 ,希望高手能夠指點。