OCI編程高級篇(九) LOB讀操作
訪問www.tomcoding.com網(wǎng)站,學(xué)習(xí)Oracle內(nèi)部數(shù)據(jù)結(jié)構(gòu),詳細(xì)文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學(xué)習(xí)高技術(shù)含量的內(nèi)容。
上一節(jié)介紹了LOB的寫操作,對應(yīng)的就是LOB的讀操作,步驟與寫操作差不多。
1. 準(zhǔn)備LOB SELECT語句,為獲取LOB定位符做準(zhǔn)備。
2. 定義輸出到LOB定位符,LOB定位符在之前要分配好。
3. 執(zhí)行LOB SELECT語句。
4. 執(zhí)行Fetch函數(shù),把LOB信息與LOB定位符關(guān)聯(lián)起來。
5. 打開LOB定位符。
6. 讀LOB數(shù)據(jù),然后處理LOB數(shù)據(jù),可以重復(fù)執(zhí)行這個步驟。
7. 關(guān)閉LOB定位符。
用到的新函數(shù)是LOB讀的函數(shù)叫做OCILobRead2(),看一下它的原型和參數(shù)。
sword OCILobRead2 ( OCISvcCtx *svchp,
OCIError *errhp,
OCILobLocator *locp,
oraub8 *byte_amtp,
oraub8 *char_amtp,
oraub8 offset,
void *bufp,
oraub8 bufl,
ub1 piece,
void *ctxp,
OCICallbackLobRead2 (cbfp)
( void *ctxp,
const void *bufp,
oraub8 lenp,
ub1 piecep
void **changed_bufpp,
oraub8 *changed_lenp
)
ub2 csid,
ub1 csfrm );
svchp是一個輸入/輸出參數(shù),OCI服務(wù)的上下文句柄。
errhp是一個輸入/輸出參數(shù),錯誤句柄,返回錯誤碼和錯誤信息文本。
locp是一個輸入?yún)?shù),LOB定位符指針。
byte_amtp是一個輸入/輸出參數(shù),要讀取的LOB字節(jié)數(shù),讀完后返回的是讀到的LOB字節(jié)數(shù),用于BLOB的讀取。
char_amtp是一個輸入/輸出參數(shù),要讀取的LOB字符數(shù),讀完后返回的是讀到的LOB字符數(shù),用于CLOB的讀取。
offset是一個輸入?yún)?shù),要讀取的LOB的偏移量,CLOB以字符計算,BLOB以字節(jié)計算,偏移量從1開始計算。
bufp是一個輸入/輸出參數(shù),指向一個數(shù)據(jù)緩沖區(qū),用于接收讀到的LOB數(shù)據(jù)。
bufl是一個輸入?yún)?shù),指定數(shù)據(jù)接收緩沖區(qū)的大小,以字節(jié)計算。
piece是一個輸入?yún)?shù),指定讀入的數(shù)據(jù)片類型。隨機讀使用OCI_ONE_PIECE。流讀取第一次讀使用OCI_FIRST_PIECE,后續(xù)的讀使用OCI_NEXT_PIECE。
ctxp是一個輸入?yún)?shù),是回調(diào)函數(shù)的上下文,可以為NULL。
cbfp是一個輸入?yún)?shù),是回調(diào)函數(shù)的指針,不使用回調(diào)函數(shù)設(shè)置為NULL。
csid是一個輸入?yún)?shù),指示緩沖區(qū)中的數(shù)據(jù)字符集,Oracle的CLOB數(shù)據(jù)在數(shù)據(jù)庫中的存儲有自己的字符集,讀到緩沖區(qū)中要進行字符集轉(zhuǎn)換,這里的csid就是轉(zhuǎn)換后數(shù)據(jù)的字符集。
csfrm是一個輸入?yún)?shù),指示緩沖區(qū)數(shù)據(jù)的字符集形式,取值SQLCS_IMPLICIT表示與數(shù)據(jù)庫字符集一致,取值SQLCS_NCHAR表示使用國際字符集。
使用上一節(jié)中寫入的LOB數(shù)據(jù),我們在這兒讀出來,看一看讀LOB的過程怎樣用OCI實現(xiàn)。
OCIEnv *envhp = NULL; OCIError *errhp = NULL; OCIServer *svrhp = NULL; OCISession *usrhp = NULL; OCISvcCtx *svchp = NULL; OCIStmt *smthp = NULL; ??int read_lob(void){ int i; sword rc; sb4 ec; int slen; ub1 piece; oraub8 amt; OCIDefine *defp; OCILobLocator *locp; char sqltxt[1024]; text errbuf[512]; char buf[4096]; /* 分配LOB定位符 */ rc = OCIDescriptorAlloc((const void *)envhp, (void **)&locp, OCI_DTYPE_LOB, 0, (void **)NULL); if (rc != OCI_SUCCESS) { OCIErrorGet(envhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIDescriptorAlloc() - [%d] %s\n", ec, errbuf); return (-1); } /* 下面執(zhí)行LOB SELECT操作 */ strcpy(sqltxt, "SELECT MESSAGE FROM test_clob_tab WHERE ID=1"); slen = strlen(sqltxt); rc = OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen, OCI_NTV_SYNTAX, OCI_DEFAULT); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIStmtPrepare() - [%d] %s\n", ec, errbuf); return (-1); } /* 定義LOB定位符輸出 */ rc = OCIDefineByPos((OCIStmt *)smthp, (OCIDefine **)&defp, (OCIError *)errhp, (ub4)1, (void *)&locp, (sb4)sizeof(OCILobLocator *), (ub2)SQLT_CLOB, (void *)NULL, (ub2 *)NULL, (ub2 *)NULL, (ub4)OCI_DEFAULT); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIDefineByPos() - [%d] %s\n", ec, errbuf); return (-1); } /* 執(zhí)行語句 */ rc = OCIStmtExecute(svchp, smthp, /* stmthp */ errhp, /* errhp */ 0, /* iters */ 0, /* rowoff */ NULL, /* snap_in */ NULL, /* snap_out */ OCI_DEFAULT); /* mode */ if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIExecute() - [%d] %s\n", ec, errbuf); return (-1); } /* 執(zhí)行fetch操作 */ rc = OCIStmtFetch(smthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIStmtFetch() - [%d] %s\n", ec, errbuf); return (-1); } /* 打開LOB */ rc = OCILobOpen(svchp, errhp, locp, OCI_LOB_READWRITE); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCILobOpen() - [%d] %s\n", ec, errbuf); return (-1); } for (i=0; ; i++) { if (i == 0) piece = OCI_FIRST_PIECE; else piece = OCI_NEXT_PIECE; amt = 4000; rc = OCILobRead2(svchp, errhp, locp, NULL, &amt, 1, buf, 4000, piece, 0, SQLCS_IMPLICIT); if (rc == OCI_NEED_DATA) { /* 讀取的數(shù)據(jù)在buf中,在這里處理數(shù)據(jù),我們只打印讀到的數(shù)據(jù)量值作為演示 */ fprintf(stdout, "read data amount=%d\n", amt); /* 進行下一次讀 */ continue; } else if (rc == OCI_SUCCESS) { /* 讀到了最后一片數(shù)據(jù),處理數(shù)據(jù)后,退出循環(huán) */ fprintf(stdout, "read data amount=%d\n", amt); break; } if (rc == OCI_ERROR) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCILobWrite2() - [%d] %s\n", ec, errbuf); return (-1); } /* 其他錯誤 */ fprntf(stderr, "Other error found !\n"); return (-1); } /* 關(guān)閉LOB */ rc = OCILobClose(svchp, errhp, locp); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCILobClose() - [%d] %s\n", ec, errbuf); return (-1); } /* 釋放LOB定位符 */ rc = OCIDescriptorFree((void *)locp, OCI_DTYPE_LOB); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIDescriptorFree() - [%d] %s\n", ec, errbuf); return (-1); } return (0); }

浙公網(wǎng)安備 33010602011771號