Oracle的BLOB字段類型可以用來保存長2進制數據。但是通常讀寫BLOB字段數據的代碼都是很羅嗦,非細心編碼很容易出錯。我把這個功能集成到我的OCI包裝庫(ORADBI)中。下面的例子就是演示如何使用ORADBI把多個文件按保存到一個字段裡。
我在另外的例子中將演示如何把BLOB字段中的數據還原為文件。
整個ORADBI是我在OCI基礎上寫的C語言API。從創作這個API到一直不斷的更新維護,已經有1年多了。我也將一直維護下去,不斷完善和添加新的功能。ORADBI是完全免費和完全開源的,使用者只要不聲明為其版權所有,可以用它做任何事情。
這是個直接利用OCI操作BLOB的例子。我相信,這是你能找到的最快捷的方法。
1)首先保證你的機器上可以使用Oracle9i或10g的客戶端。Oracle10g只需要安裝Windows即時客戶端。
2)下載我編寫的ORADBI庫。我提供了完整的庫代碼和例子程序。
http://download.csdn.Net/source/589896
3)定義你要保存的文件路徑,如:
const char* arrLobFiles[] = {
"E:\eBookLib-計算機\C&C++\APress.Cryptography in C and C++_SourceCode.rar",
"E:\eBookLib-計算機\C&C++\Charles.River.Media.Algorithms.For.Compiler.Design.eBook-LiB.chm",
"E:\eBookLib-計算機\C&C++\C與C++中的異常處理.pdf",
"E:\eBookLib-計算機\C&C++\The art of assmebly language.pdf",
"E:\eBookLib-計算機\C&C++\Jones.And.Bartlett.Publishers.Foundations.Of.Algorithms.Using.Cpp.Pseudocode.3rd.Edition.eBook-Li.chm",
"E:\eBookLib-計算機\C&C++\The C++ Standard Library.pdf",
"E:\eBookLib-計算機\C&C++\GCC--CompleteReference.pdf",
"E:\eBookLib-計算機\C&C++\VC技術內幕第五版.chm",
"E:\eBookLib-計算機\Network&Tcpip\ALTHOS.Introduction.To.Data.Networks.PDN.LAN.MAN.WAN.and.Wireless.Data.TechnologIEs.and.Systems.e.chm",
"E:\eBookLib-計算機\Network&Tcpip\Digital Satellite Communications 2nd Ed - book.pdf",
"E:\eBookLib-計算機\Network&Tcpip\McGraw.Hill.Storage.Networks.The.Complete.Reference.chm",
"E:\eBookLib-計算機\Network&Tcpip\UNIX Network Programming Volume 1_3rd Edition-The Sockets Networking API.chm"
};
4)創建合適的表在Oracle9i或10g中,我的例子是采用如下的語句創建的表:
-- Create table
create table TEST
(
BM VARCHAR2(10),
NAME VARCHAR2(100),
BIRTH DATE,
DATA BLOB
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
5)更改適合你的登錄方式,改變下面的預定義值:
#define ORADB_SERVICE "CHEUNG"
#define ORADB_LOGUSER "mineusr"
#define ORADB_PASSWord "minepwd"
下面是寫文件到BLOB字段的完整的例子:
//
// write_blobfile.c - 寫BLOBFILE的例子
// 使用ORADBI.dll
// [email protected], 保留所有權利
//
// 內存洩漏檢測
// 在需要檢測的地方放置語句:
// _CrtDumpMemoryLeaks();
// 以下3句的次序不能改變
#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
// 包含唯一的ORADBI 頭文件
#include "../oradbi.h"
#ifdef _DEBUG
#pragma comment(lib, "../oradbi_dll/debug/oradbid.lib")
#else
#pragma comment(lib, "../oradbi_dll/release/oradbi.lib")
#endif
#define ORADB_SERVICE "CHEUNG"
#define ORADB_LOGUSER "mineusr"
#define ORADB_PASSWord "minepwd"
/*==================================================
-- Create table
create table TEST
(
BM VARCHAR2(10),
NAME VARCHAR2(100),
BIRTH DATE,
DATA BLOB
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
====================================================*/
//
// 下面的文件被插入到一個DATA字段
// 在這裡定義你要插入的文件, 這些文件必須存在
//
const char* arrLobFiles[] = {
"E:\eBookLib-計算機\C&C++\APress.Cryptography in C and C++_SourceCode.rar",
"E:\eBookLib-計算機\C&C++\Charles.River.Media.Algorithms.For.Compiler.Design.eBook-LiB.chm",
"E:\eBookLib-計算機\C&C++\C與C++中的異常處理.pdf",
"E:\eBookLib-計算機\C&C++\The art of assmebly language.pdf",
"E:\eBookLib-計算機\C&C++\Jones.And.Bartlett.Publishers.Foundations.Of.Algorithms.Using.Cpp.Pseudocode.3rd.Edition.eBook-Li.chm",
"E:\eBookLib-計算機\C&C++\The C++ Standard Library.pdf",
"E:\eBookLib-計算機\C&C++\GCC--CompleteReference.pdf",
"E:\eBookLib-計算機\C&C++\VC技術內幕第五版.chm",
"E:\eBookLib-計算機\Network&Tcpip\ALTHOS.Introduction.To.Data.Networks.PDN.LAN.MAN.WAN.and.Wireless.Data.TechnologIEs.and.Systems.e.chm",
"E:\eBookLib-計算機\Network&Tcpip\Digital Satellite Communications 2nd Ed - book.pdf",
"E:\eBookLib-計算機\Network&Tcpip\McGraw.Hill.Storage.Networks.The.Complete.Reference.chm",
"E:\eBookLib-計算機\Network&Tcpip\UNIX Network Programming Volume 1_3rd Edition-The Sockets Networking API.chm"
};
//
// 顯示如何把多個文件插入到BLOB字段
//
void insert_blob_data()
{
lresult rc;
ora_error_t err; // 不需要釋放
ora_param p[4];
ora_datetime dt;
ora_connection con = 0;
ora_sqlstmt stmt = 0;
// 用於綁定LOB變量的結構
ORADBI_InBind inbind;
// 利用ORADBI自帶的寫blobfile功能
// ORA_inbind_lobfile_init 必須在ORA_sqlstmt_bind_lob之前調用
ORA_inbind_lobfile_init(&inbind, 0, arrLobFiles, sizeof(arrLobFiles)/sizeof(arrLobFiles[0]), &err);
// 創建連接
rc = ORA_connection_create( &con, ORADB_SERVICE, ORADB_LOGUSER, ORADB_PASSWord, OCI_THREADED|OCI_OBJECT, FALSE, &err);
assert(rc==_SUCCESS);
// 創建SQL
rc = ORA_sqlstmt_create( &stmt, con, "insert into TEST (BM,NAME,BIRTH,DATA) values (:bm,:name,:birth,:blob)", -1, 0, &err);
assert(rc==_SUCCESS);
// 綁定變量
rc = ORA_sqlstmt_bind (stmt, ":bm", ODT_TEXT, 0, &p[0], &err);
assert(rc==_SUCCESS);
rc = ORA_sqlstmt_bind (stmt, ":name", ODT_TEXT, 100, &p[1], &err);
assert(rc==_SUCCESS);
rc = ORA_sqlstmt_bind (stmt, ":birth", ODT_DATE, 0, &p[2], &err);
assert(rc==_SUCCESS);
// 綁定BLOB變量
rc = ORA_sqlstmt_bind_lob (stmt, ":blob", 0, &inbind, 0, &p[3], &err);
assert(rc==_SUCCESS);
// 設置變量的值
rc = ORA_param_set_string(p[0], "2008", -1, &err);
rc = ORA_param_set_string(p[1], "BeiJing", -1, &err);
ORA_datetime_create(&dt, 1);
rc = ORA_param_set_datetime(p[2], dt, &err);
ORA_datetime_free(dt);
// 執行插入
rc = ORA_sqlstmt_execute(stmt, MOD_DEFAULT, 0, &err);
assert(rc==_SUCCESS);
rc = ORA_connection_commit(con, &err);
assert(rc==_SUCCESS);
// 釋放結束
ORA_inbind_lobfile_free(&inbind);
ORA_sqlstmt_free(stmt);
ORA_connection_free(con);
}
//
// 主程序
//
int main(int argc, char* argv[])
{
insert_blob_data();
_CrtDumpMemoryLeaks();
return 0;
}