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)容。
前面我們看到在LOB操作之前都要執(zhí)行一個LOB SELECT操作,用于得到LOB定位符,尤其在插入一個空LOB,隨后寫入的情況,操作起來非常繁瑣。那時我們希望有一種方法能簡潔的得到LOB定位符,現(xiàn)在我們來看一下。
OCI在SQL語句INSERT,UPDATE,DELETE后面可以跟隨一個RETURNING字句,相當(dāng)于一個查詢語句跟一個DML語句合并在一起執(zhí)行,先執(zhí)行完DML語句,然后執(zhí)行一個查詢語句,把查詢的內(nèi)容返回給程序。
這里仿照前面插入空LOB然后寫入數(shù)據(jù)的例子,看看怎樣使用這個字句。我們插入一條數(shù)據(jù),SQL語句是INSERT INTO test_clob_tab (ID, MESSAGE) VALUES (2, EMPTY_CLOB()),然后執(zhí)行SELECT MESSAGE FROM test_clob_tab WHERE ID=2,定義一個LOB定位符的輸出變量,得到LOB定位符。如果合并到一起SQL語句是這樣的INSERT INTO test_clob_tab (ID, MESSAGE) VALUES (2, EMPTY_CLOB()) RETURNING MESSAGE INTO :1。然后通過綁定函數(shù)綁定一個LOB定位符的輸出變量,只要執(zhí)行一次,就能插入空LOB數(shù)據(jù)然后得到一個LOB定位符。是不是簡單多了?尤其在一次插入多個空LOB然后分別寫入的情況,使用這種方法,更簡單,代碼更簡潔。
下面我們還是通過一個例子來看看完整的代碼怎樣實現(xiàn)。
OCIEnv *envhp = NULL; OCIError *errhp = NULL; OCIServer *svrhp = NULL; OCISession *usrhp = NULL; OCISvcCtx *svchp = NULL; OCIStmt *smthp = NULL; ??int insert_one_lob(void){ int i; sword rc; sb4 ec; int slen; sb2 ind_msg; ub2 alen_msg; ub1 piece; oraub8 amt; OCIBind *bndp; OCILobLocator *locp; char sqltxt[1024]; text errbuf[512]; strcpy(sqltxt, "INSERT INTO test_clob_tab (ID, MESSAGE) values (2, EMPTY_CLOB()) RETURNING MESSAGE INTO :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 = 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); } /* 綁定LOB定位符 */ rc = OCIBindByPos((OCIStmt *)smthp, (OCIBind **)&bndp, errhp, (ub4)1, (void *)&locp, (sb4)sizeof(OCILobLocator *), (ub2)SQLT_CLOB, (void *)&ind_msg, /* indp */ (ub2 *)&alen_msg, /* alenp */ (ub2 *)NULL, /* column return code pointer */ (ub4)0, /* maxarr_len */ (ub4 *)NULL, /* curelep */ (ub4)OCI_DEFAULT); /* mode */ if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCIBindByPos() - [%d] %s\n", ec, errbuf); return (-1); } ind_msg = 0; alen_msg = sizeof(OCILobLocator *); /* 執(zhí)行語句 */ rc = OCIStmtExecute(svchp, smthp, /* stmthp */ errhp, /* errhp */ 1, /* 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); } /* 打開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<20; i++) { if (i == 0) piece = OCI_FIRST_PIECE; else if (i == 19) piece = OCI_LAST_PIECE; else piece = OCI_NEXT_PIECE; sprintf(buf, "%02d", i); memset(&buf[2], 3998, 'B'); amt = 4000; rc = OCILobWrite2(svchp, errhp, locp, NULL, &amt, 1, buf, 4000, piece, 0, SQLCS_IMPLICIT); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCILobWrite2() - [%d] %s\n", ec, errbuf); 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); } /* 提交改變 */ rc = OCITransCommit(svchp, errhp, OCI_DEFAULT); if (rc != OCI_SUCCESS) { OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR); fprintf(stderr, "OCITransCommit() - [%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); }
這種方法也有局限性,只能用于插入或更新LOB的操作中,其他的操作還是要先執(zhí)行LOB SELECT操作得到LOB定位符才行。

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