pro c 访问 MySQL_Pro*C OCI OCCI 及OCI介绍
Pro*C? OCI
OCCI? 這三種都是C/C++訪問數(shù)據(jù)庫(kù)的手段。
Pro*C:
內(nèi)嵌SQL,預(yù)編譯后把內(nèi)嵌SQL處理為ORACLE標(biāo)準(zhǔn)運(yùn)行庫(kù)的調(diào)用,然后再象編譯一般的C程序一樣進(jìn)行編譯、連接、運(yùn)行。
1.proc XXX.pc
2.gcc/g++ XXX.c –lclntsh
(PRO*C的預(yù)編譯,也可直接MAKEFILE搞定)
OCI/OCCI:
oracle提供的訪問oracle數(shù)據(jù)庫(kù)的API,比較繁瑣,但是完全符合C/C++語(yǔ)言的訪問流程,清晰,便于理解,調(diào)試。
OCI:Oracle Call Interface ;(C語(yǔ)言實(shí)現(xiàn))
OCCI:Oracle C++ Call Interface;(C++語(yǔ)言實(shí)現(xiàn))
OCI使用步驟大致介紹
OCI(Oracle Call
Inte***ce)是由頭文件和庫(kù)函數(shù)等組成的一套Oracle數(shù)據(jù)庫(kù)應(yīng)用程序編程接口工具,OCI程序?qū)嵸|(zhì)上就是用高級(jí)語(yǔ)言寫的程序,其特點(diǎn)是內(nèi)部含有對(duì)OCI子函數(shù)庫(kù)的調(diào)用。
OCI程序?qū)﹂_發(fā)環(huán)境的要求相對(duì)較低,只要有C語(yǔ)言的OCI開發(fā)工具包和C編譯器就可以,程序設(shè)計(jì)相比PRO*C復(fù)雜了點(diǎn)。
1、創(chuàng)建和初始化OCI環(huán)境
首先要在源程序中包含OCI頭文件:#include
OCI環(huán)境即OCI函數(shù)的工作環(huán)境,在調(diào)用其他函數(shù)之前必須先調(diào)用OCIInitialize()和OCIEnvInit()函數(shù)創(chuàng)建和初始化OCI環(huán)境,其他OCI函數(shù)要在這個(gè)環(huán)境中才能執(zhí)行。
先定義變量:
OCIEnv**?? m_envhp;
OCIError*? m_errhp;
OCIServer* m_srvhp;
OCISvcCtx* m_svchp;
OCIStmt *? m_stmthp;
OCIInitialize(
(ub4) OCI_DEFAULT,
(dvoid *)0,
(dvoid * (*)(dvoid *, size_t))0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *))0
);
OCIEnvInit(
(OCIEnv **)&m_envhp,
OCI_DEFAULT, (size_t)0,
(dvoid **)0
);
其中m_envhp為輸出參數(shù),是一個(gè)指向OCI環(huán)境句柄的指針,OCI_DEFAULT
是OCI環(huán)境的初始化模式。OCIEnvInit()函數(shù)中的size_t類型變量為分配給用戶的內(nèi)存數(shù)量,dvoid
**類型變量指向用戶的內(nèi)存區(qū)域,該區(qū)域的大小等于size_t類型變量。
OCI函數(shù)中,大量使用OCI定義的數(shù)據(jù)類型和宏,其定義可參考$ORACLE_HOME/rdbms/demo目錄下的oci.h頭文件。
2、申請(qǐng)句柄
句柄是指向OCI庫(kù)所分配的內(nèi)存區(qū)域的指針,該內(nèi)存區(qū)域中的數(shù)據(jù)由OCI庫(kù)維護(hù),應(yīng)用程序可通過句柄訪問其中的數(shù)據(jù)。下面是應(yīng)用程序中最常用的幾個(gè)句柄:
OCIHandleAlloc(
(dvoid *)m_envhp,
(dvoid **)&m_errhp,
OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0
);
OCIHandleAlloc(
(dvoid *)m_envhp,
(dvoid **)&m_srvhp,
OCI_HTYPE_SERVER,
(size_t)0,
(dvoid **)0
);
OCIHandleAlloc(
(dvoid *)m_envhp,
(dvoid **)&m_svchp,
OCI_HTYPE_SVCCTX,
(size_t) 0,
(dvoid **)0
);
OCIHandleAlloc(
(dvoid *)m_envhp,
(dvoid **)&m_stmthp,
OCI_HTYPE_STMT,
(size_t)0,
(dvoid **)0
);
其中m_errhp為新申請(qǐng)的句柄,m_envhp為它的父環(huán)境句柄,OCI_HTYPE_ERROR為句柄類型,表示這是一個(gè)錯(cuò)誤報(bào)告句柄,OCI_HTYPE_SERVER表示服務(wù)器句柄,OCI_HTYPE_SVCCTX表示服務(wù)環(huán)境句柄,OCI_HTYPE_STMT表示語(yǔ)句句柄。
存儲(chǔ)在句柄中的數(shù)據(jù)稱為句柄屬性,所有OCI句柄都具有屬性,可以調(diào)用OCIAttrGet()和OCIAttrSet()函數(shù)來(lái)讀取、設(shè)置句柄屬性。
3、連接服務(wù)器建立會(huì)話
首先調(diào)用
OCIServerAttach(m_srvhp, m_errhp, (text
*)"",
strlen(""), OCI_DEFAULT);
函數(shù)建立與指定服務(wù)器的連接,text
*類型變量為空,表示連接默認(rèn)數(shù)據(jù)庫(kù)服務(wù),OCI_DEFAULT表示應(yīng)用程序的操作模式為阻塞模式,在這種方式下,只有當(dāng)OCI調(diào)用完成后才將控制權(quán)返回給客戶端應(yīng)用程序。
然后調(diào)用
OCILogon(m_envhp,m_errhp, &m_svchp,
(text*)m_szUser,strlen(m_szUser), (text*)m_szPassword,
strlen(m_szPassword), (text*)m_szDbName, strlen(m_szDbName));
建立數(shù)據(jù)庫(kù)會(huì)話。此函數(shù)隱含申請(qǐng)服務(wù)器句柄和用戶會(huì)話句柄,登錄后,句柄是只讀的,不能再設(shè)置句柄屬性。
4、執(zhí)行SQL語(yǔ)句并處理數(shù)據(jù)
將要執(zhí)行的SQL語(yǔ)句copy到szSqlStr字符串中:
snprintf( szSqlStr, sizeof(szSqlStr), "select
PASSWORD from USERS where USERNAME=’chen’
");
執(zhí)行下列語(yǔ)句:
OCIStmtPrepare(m_stmthp, m_errhp, (text*)szSqlStr, (ub4)
strlen(szSqlStr), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
//準(zhǔn)備SQL語(yǔ)句
OCIDefine *defnp0 = (OCIDefine *) 0; //定義輸出變量
OCIDefineByPos( m_stmthp, &defnp0, m_errhp, 1,
(dvoid *)szUSERNAME, 100, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2
*)0, OCI_DEFAULT); //綁定變量
OCIStmtExecute( m_svchp, m_stmthp, m_errhp, (ub4) 1, (ub4) 0,
(OCISnapshot *) NULL,(OCISnapshot *) NULL, (ub4) OCI_DEFAULT);
//執(zhí)行SQL語(yǔ)句
5、結(jié)束會(huì)話斷開數(shù)據(jù)庫(kù)連接 OCILogoff( m_svchp,
m_errhp );
6、斷開與數(shù)據(jù)源的連接,釋放句柄
OCIServerDetach( m_srvhp, m_errhp, OCI_DEFAULT ); //斷開與數(shù)據(jù)源的連接
OCIHandleFree((dvoid *) m_stmthp, OCI_HTYPE_STMT); //釋放句柄
OCIHandleFree((dvoid *) m_svchp, OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *) m_srvhp, OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *) m_errhp, OCI_HTYPE_ERROR)
3.7生成可執(zhí)行文件(兩種方法)
(1)同普通的C程序:
gcc -o exampled –I.
–I$(ORACLE_HOME)/precomp/public example.c
(2)利用Oracle自帶的Make文件:
首先將$ORACLE_HOME/rdbms/demo/demo_rdbms.mk文件copy到OCI源程序所在的目錄,將源文件編譯為目標(biāo)文件:
#gcc –c example.o -I$(ORACLE_HOME)/rdbms/demo
-I$(ORACLE_HOME)/network/public -I$(ORACLE_HOME)/rdbms/public/
example.c
然后用命令:#make -f demo_rdbms.mk build OBJ*=**ample.o
EXE=exampled,exampled就為生成的可執(zhí)行文件
OCI常用函數(shù)說明:
一、初始化OCI程序環(huán)境。
OCI8使用OCIInitialize函數(shù)來(lái)初始化OCI。這是使用OCI8與數(shù)據(jù)庫(kù)建立會(huì)話必須的一步;同時(shí),必須是第一步。如果成功,則返回0。
函數(shù)原型:sword OCIInitialize (ub4 mode,CONST dvoid *ctxp,CONST dvoid
*(*malocfp) (/* dvoid *ctxp,size_t size _* /),
CONST dvoid *(*ralocfp)(/*_ dvoid *ctxp,dvoid *memptr,size_t
newsize _* /),
CONST void (*mfreefp)(/*_ dvoid *ctxp,dvoid *memptr _* /))
參數(shù)說明:
mode——詳細(xì)說明OCI初始化(Initialize)模式(mode)。它的取值如下:
OCI_DEFAULT——缺省模式;
OCI_THREADED——多線程模式;在該模式下,各并發(fā)處理中不為用戶所見的內(nèi)在數(shù)據(jù)結(jié)構(gòu)受各自線程的保護(hù),而不受別的線程干擾;
OCI_OBJECT——使用目標(biāo)特性;
OCI_SHARED——使用共享內(nèi)存;
OCI_EVENTS——
Mode參數(shù)可以擁有多個(gè)值,以“|”符號(hào)分隔各取值項(xiàng)。
*Ctxp——用戶定義的內(nèi)存回調(diào)程序;默認(rèn)為0
*(*malocfp)——用戶定義的內(nèi)存分配程序;默認(rèn)為0
*(*ralocfp)——重新分配內(nèi)存程序;默認(rèn)為0
*memptr 是指向內(nèi)存塊的指針;
*mfreefp——用戶定義的內(nèi)存釋放程序;默認(rèn)為0
該函數(shù)使用舉例如下:
OCIInitialize((ub4) OCI_THREADED | OCI_OBJECT,
(dvoid *)0,(dvoid *(*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *,dvoid *,size_t))0,
(void (*)(dvoid *,dvoid *)) 0 )
注意!OCIEnvCreate() 可以代替OCIInitialize() 和OCIEnvInit()
二、 初始化OCI環(huán)境句柄。
在初始化OCI程序環(huán)境以后,使用OCIEnvInit來(lái)初始化OCI的環(huán)境句柄,該函數(shù)成功返回0。
函數(shù)原型:sword OCIEnvInit(OCIEnv **envhpp,
ub4 mode,
size_t xtramemsz,
dvoid **usrmempp )
參數(shù)說明:
**envhpp——指向環(huán)境句柄的指針;
mode——指定初始化環(huán)境句柄的模式,其取值如下:
OCI_DEFAULT——缺省模式;在缺省模式下,OCI庫(kù)始終互斥各環(huán)境句柄;
OCI_NO_MUTEX——非互斥模式;在該模式下,OCI庫(kù)各環(huán)境句柄并不互斥,所有的掉用都使用同一個(gè)環(huán)境句柄,并且只能有一個(gè)環(huán)境句柄起作用。
OCI_ENV_NO_UCB——禁止回滾模式;該模式用以禁止在環(huán)境句柄初始化過程中的動(dòng)態(tài)CALL_BACK函數(shù)掉用;
Xtramemsz——指定在該環(huán)境句柄生存期內(nèi)分配內(nèi)存的數(shù)量;
**usrmempp——指向Xtramemsz參數(shù)的指針;usermempp參數(shù)是函數(shù)返回值;
該函數(shù)使用舉例如下:
應(yīng)用例子:OCIEnvInit((OCIEnv **) envhp,
(ub4) OCI_DEFAULT,
(size_t) 0,(dvoid **) 0)
三、 分配各OCI句柄。
一個(gè)OCI連接在建立前,還需要將所需要的句柄一一分配成功,在OCI8里,使用函數(shù)OCIHandleAlloc來(lái)分配各句柄,成功返回0。
函數(shù)原型:sword OCIHandleAlloc(CONST dvoid *parenth,
dvoid **hndlpp,
ub4 type,
size_t xtramem_sz,
dvoid **usrmempp )
參數(shù)說明:
*parenth——已初始化后的環(huán)境句柄;
**hndlpp——函數(shù)執(zhí)行成功后,返回的一個(gè)OCI句柄;該返回值的具體含義由type參數(shù)來(lái)決定;
type——參數(shù)hndlpp的返回值的類型;其常用取值如下:
OCI_HTYPE_SVCCTX——返回一個(gè)服務(wù)類型的句柄;
OCI_HTYPE_ERROR——返回一個(gè)錯(cuò)誤類型的句柄;
OCI_HTYPE_SESSION——返回一個(gè)會(huì)話類型的句柄;
OCI_HTYPE_SERVER——返回一個(gè)服務(wù)器類型的句柄;
OCI_HTYPE_STMT——返回一個(gè)陳述類型的句柄;
其中,陳述類型的句柄是在創(chuàng)建與數(shù)據(jù)庫(kù)會(huì)話成功后,將要對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作時(shí)分配的,其余類型的句柄是在環(huán)境句柄初始化后分配的;
xtramem_sz——指定在該句柄生存期內(nèi)分配內(nèi)存的數(shù)量;
**usrmempp——指向xtramem_sz參數(shù)的指針,由函數(shù)返回;
該函數(shù)使用舉例如下:OCIHandleAlloc((dvoid *) *envhp,
(dvoid **) errhp,
(ub4) OCI_HTYPE_ERROR,
(size_t) 0,
(dvoid **) 0)
四、
為OCI操作數(shù)據(jù)源創(chuàng)建存儲(chǔ)路徑 (以給定的方式設(shè)置服務(wù)器連接指針的參數(shù))。
分配各OCI句柄后,還需要做的工作是為OCI操作數(shù)據(jù)源創(chuàng)建存儲(chǔ)路徑,并將各項(xiàng)參數(shù)設(shè)置到相應(yīng)的句柄中,這項(xiàng)工作由函數(shù)OCIServerAttach和OCIAttrSet來(lái)實(shí)現(xiàn)。成功,返回0。
函數(shù)原型:sword OCIServerAttach(OCIServer *srvhp,
OCIError *errhp,
CONST text *dblink,
sb4 dblink_len,
ub4 mode )
參數(shù)說明:
*srvhp——已分配成功的服務(wù)器句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
*dblink——登陸數(shù)據(jù)庫(kù)的實(shí)例名;
dblink_len——參數(shù)*dblink字符串的長(zhǎng)度;
mode——指定不同操作的模式。現(xiàn)在只有一種模式可選:OCI_DEFAULT。
該函數(shù)使用舉例如下:OCIServerAttach(srvhp, errhp,
(text *) cstring,
(sb4) strlen((char *)cstring), (ub4) OCI_DEFAULT))
函數(shù)原型:sword OCIAttrGet (CONST dvoid *trgthndlp,
ub4 trghndltyp,
dvoid *attributep,
ub4 *sizep,
ub4 attrtype,
OCIError *errhp )
參數(shù)說明:
*trgthndlp——需要設(shè)置的句柄,該句柄在這之前已分配成功;該參數(shù)由trghndltyp參數(shù)決定;
trghndltyp——參數(shù)trgthndlp的類型,其取值參見OCIHandleAlloc函數(shù)說明中的type參數(shù)說明;
*attributep——設(shè)置參數(shù)trgthndlp的值;
*sizep——attributep參數(shù)指向的字符串長(zhǎng)度;
attrtype——參數(shù)attributep的類型;其取值如下:
OCI_ATTR_SERVER——服務(wù)器類型;
OCI_ATTR_USERNAME——用戶名類型
OCI_ATTR_PASSWORD——用戶密碼類型
OCI_ATTR_SESSION——會(huì)話類型;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
該函數(shù)使用舉例如下:OCIAttrSet((dvoid *) svchp,
(ub4) OCI_HTYPE_SVCCTX,
(dvoid *) srvhp,
(ub4) 0,
(ub4) OCI_ATTR_SERVER,
errhp))
(注:此時(shí)該函數(shù)的意思是將服務(wù)器句柄設(shè)置到服務(wù)句柄中,其類型為服務(wù)器類型)
說明:在登陸數(shù)據(jù)庫(kù)前以給定的方式設(shè)置服務(wù)器連接指針的參數(shù)時(shí),attrtype參數(shù)的所有類型都需要設(shè)置到服務(wù)句柄中。設(shè)置的步驟為:先將服務(wù)器句柄設(shè)置到服務(wù)句柄中,然后將用戶名、密碼設(shè)置到會(huì)話句柄中,在調(diào)用OCISessionBegin函數(shù)成功后,再將會(huì)話句柄設(shè)置到服務(wù)句柄中。
五、 創(chuàng)建并開始與數(shù)據(jù)庫(kù)的會(huì)話
創(chuàng)建和開始與數(shù)據(jù)庫(kù)的會(huì)話使用函數(shù)OCISessionBegin來(lái)實(shí)現(xiàn),其目的是建立與數(shù)據(jù)庫(kù)的會(huì)話連接;函數(shù)成功,返回0。
函數(shù)原型:sword OCISessionBegin (OCISvcCtx *svchp,
OCIError *errhp,
OCISession *authp,
ub4 credt,
ub4 mode))
參數(shù)說明:
*svchp——已分配并設(shè)置成功的服務(wù)句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
*authp——已分配并設(shè)置了用戶名、密碼的會(huì)話句柄;
credt——建立用戶會(huì)話的類型;其取值如下:
OCI_CRED_RDBMS——需要使用用戶名和密碼來(lái)建立會(huì)話;
OCI_CRED_EXT——不需要使用用戶名和密碼來(lái)建立會(huì)話;
mode——操作的模式;其取值如下:
OCI_DEFAULT——缺省模式;在該模式下只支持一個(gè)會(huì)話句柄;
OCI_MIGRATE——移動(dòng)會(huì)話模式;在該模式下,新的會(huì)話連接會(huì)以不同的會(huì)話句柄返回;使用該模式創(chuàng)建新的會(huì)話時(shí),必須已存在一個(gè)不可移動(dòng)會(huì)話模式的會(huì)話連接。也就是說,一個(gè)移動(dòng)會(huì)話模式的會(huì)話連接必須有一個(gè)不可移動(dòng)模式的連接作為父連接;
OCI_SYSDBA——在該模式下,會(huì)鑒別用戶是否以SYSDBA形式對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問;
OCI_SYSOPER——在該模式下,會(huì)鑒別用戶是否以SYSOPER形式對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問;
OCI_PRELIM_AUTH——這種模式和OCI_SYSDBA、OCI_SYSOPER一起使用,作為某些訪問任務(wù)的鑒別;
該函數(shù)使用舉例如下:OCISessionBegin(svchp,
errhp,
authp,
OCI_CRED_RDBMS,
OCI_DEFAULT)
六、
取得errhp承載的錯(cuò)誤原因。
若某函數(shù)執(zhí)行出錯(cuò),則可以使用函數(shù)OCIErrorGet來(lái)取得錯(cuò)誤原因,從而能得到某些提示。
函數(shù)原型:sword OCIErrorGet (dvoid *hndlp,
ub4 recordno,
text *sqlstate,
sb4 *errcodep,
text *bufp,
ub4 bufsiz,
ub4 type )
參數(shù)說明:
*hndlp——錯(cuò)誤類型句柄errhp;
recordno——錯(cuò)誤查找的原始位置,從1開始,其缺省值為1;
*sqlstate——OCI8不支持,缺省值為NULL;
*errcodep——ORACLE錯(cuò)誤返回代碼,由函數(shù)返回;初始值可以為(sb4)0;
*bufp——錯(cuò)誤信息提示,由函數(shù)以字符串形式返回;
bufsiz——bufp參數(shù)原始字符串長(zhǎng)度;
type——句柄類型;其取值為OCI_HTYPE_ERR或著為OCI_HTYPE_ENV;缺省值為OCI_HTYPE_ERR;
該函數(shù)使用舉例如下:OCIErrorGet((dvoid *) errhp,
(ub4) 1,
(text *) NULL,
&errcode,
(text *)msgbuf,
(ub4) sizeof(msgbuf),
(ub4) OCI_HTYPE_ERROR)
七、 準(zhǔn)備執(zhí)行
用戶定義的SQL或PL/SQL陳述語(yǔ)句。
在執(zhí)行SQL或PL/SQL語(yǔ)句前,需要對(duì)該語(yǔ)句執(zhí)行分析、出錯(cuò)檢查,并和陳述句柄棒定起來(lái),使用函數(shù)OCIStmtPrepare來(lái)進(jìn)行這一系列操作。該函數(shù)在執(zhí)行陳述語(yǔ)句前必須使用;成功,返回0;
函數(shù)原型:sword OCIStmtPrepare ( OCIStmt *stmtp,
OCIError *errhp,
CONST text *stmt,
ub4 stmt_len,
ub4 language,
ub4 mode)
參數(shù)說明:
*stmtp——已分配成功的陳述句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
*stmt——用戶定義的需要執(zhí)行的SQL或PL/SQL陳述語(yǔ)句;
stmt_len——用戶定義的需要執(zhí)行的陳述語(yǔ)句的長(zhǎng)度;該參數(shù)的值不能為0;
language——語(yǔ)法模式;聲明是本地語(yǔ)法,還是V7模式語(yǔ)法。其取值如下:
OCI_V7_SYNTAX——ORACLE的V7分析語(yǔ)法;
OCI_NTV_SYNTAX——語(yǔ)法依賴于服務(wù)器的版本;
mode——模式;其缺省值為OCI_DEFAULT;
該函數(shù)使用舉例如下:OCIStmtPrepare(stmthp,
errhp,
sqlcommand,
(ub4)strlen((char *)sqlcommand),
(ub4) OCI_NTV_SYNTAX,
(ub4) OCI_DEFAULT)
八、 定義輸出變量。
OCI執(zhí)行陳述語(yǔ)句后,將所選擇的變量值返回輸出,此時(shí)需有用戶定義的地址空間來(lái)容納這些返回值。使用函數(shù)OCIDefineByPos通過在陳述語(yǔ)句中標(biāo)志某變量在用戶定義的變量集合中的位置來(lái)定義變量;若該函數(shù)執(zhí)行成功,返回0。
函數(shù)原型:sword OCIDefineByPos (OCIStmt *stmtp,
OCIDefine **defnpp,
OCIError *errhp,
ub4 position,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *rlenp,
ub2 *rcodep,
ub4 mode )
參數(shù)說明:
*stmtp——用以進(jìn)行查詢的陳述語(yǔ)句句柄;該句柄必須是已經(jīng)分配成功的句柄;
**defnpp——用戶定義的變量集合的指針;該參數(shù)指針從下標(biāo)0開始,依次遞增一個(gè)數(shù)組單元;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
position——需要定義的變量在定義句柄的列表中的位置,從1開始;例如:
SELECT empno, ssn, mgrno FROM employees;
則empno的position值為1,ssn的position的值為2,mgrno的position值為3;以此類推。
*valuep——需要定義的變量的在執(zhí)行成功后的存儲(chǔ)地址;如果提取出來(lái)的數(shù)據(jù)有多項(xiàng),則該參數(shù)可以使用數(shù)組;
value_sz——valuep參數(shù)的指向的存儲(chǔ)地址空間的長(zhǎng)度;
dty——需要定義的變量的數(shù)據(jù)類型;SQLT_STR表示該變量是個(gè)字符串變量;SQLT_INT則表示該變量是個(gè)整型變量;
*indp——變量或數(shù)組指示器,默認(rèn)為0;
*rlenp——變量或數(shù)組長(zhǎng)度指示器,默認(rèn)為0;
*rcodep——即將提取的變量的值指示器,默認(rèn)為0;
mode——變量提取模式。其取值為OCI_DEFAULT或OCI_DYNAMIC_FETCH;OCI_DYNAMIC_FETCH用于在提取資料過程中,需要?jiǎng)討B(tài)資料的時(shí)候,此時(shí)必須用CIDefineDynamic函數(shù)建立一個(gè)回調(diào)函數(shù)用以提取數(shù)據(jù);這種情況下,valuep和value_sz參數(shù)可以忽略;
該函數(shù)使用舉例如下:OCIDefineByPos(stmthp, &dfnhp[4],
errhp, (ub4) 5,
(dvoid *) &No[0],
(sb4) sizeof(No[0]),
(ub2) SQLT_INT,
(dvoid *) 0,
(ub2 *) 0,
(ub2 *) 0,
(ub4) OCI_DEFAULT)
補(bǔ)充說明:如果輸出變量是多行資料,則valuep參數(shù)應(yīng)該為一個(gè)用戶定義了大小的靜態(tài)數(shù)組的初始地址,其大小為輸出變量的行數(shù)與該變量自身大小的乘積。此時(shí),在函數(shù)后面還需要使用另一個(gè)函數(shù)OCIDefineArrayOfStruct來(lái)定義該數(shù)組。函數(shù)OCIDefineArrayOfStruct說明如下:
函數(shù)原形:sword OCIDefineArrayOfStruct(OCIDefine *defnp,
OCIError *errhp,
ub4 pvskip,
ub4 indskip,
ub4 rlskip,
ub4 rcskip )
參數(shù)說明:
*defnp——從函數(shù)OCIDefineByPos返回的對(duì)應(yīng)該變量的定義句柄,對(duì)應(yīng)于OCIDefineByPos函數(shù)的第二項(xiàng)參數(shù)defnpp;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
pvskip——從本條記錄中該變量的存儲(chǔ)地址的到下條記錄中該變量的存儲(chǔ)地址之間的大小;也就是定義的一條記錄的存儲(chǔ)空間的大小;
indskip——默認(rèn)為0;
rlskip——默認(rèn)為0;
rcskip——默認(rèn)為0;
該函數(shù)使用舉例說明如下(對(duì)應(yīng)于函數(shù)OCIDefineByPos的例子):
OCIDefineArrayOfStruct(dfnhp[4],
errhp,
sizeof(No[0]),
0,0,0)
九、 定義輸入變量
OCI在執(zhí)行陳述語(yǔ)句時(shí),有時(shí)需要向該語(yǔ)句傳遞輸入值,OCI8通過函數(shù)OCIBindByPos或OCIBindByName來(lái)實(shí)現(xiàn)該功能,OCIBindByPos將需要輸入的變量與與其對(duì)應(yīng)的參數(shù)值的位置綁定起來(lái),從而實(shí)現(xiàn)向陳述語(yǔ)句中傳遞值的效果,而OCIBindByName則是通過綁定相應(yīng)的變量名稱來(lái)實(shí)現(xiàn)輸入值的傳遞。
函數(shù)原型:sword OCIBindByPos ( OCIStmt *stmtp,
OCIBind **bindpp,
OCIError *errhp,
ub4 position,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *alenp,
ub2 *rcodep,
ub4 maxarr_len,
ub4 *curelep,
ub4 mode )
參數(shù)說明:
*stmtp——用以進(jìn)行查詢的陳述語(yǔ)句句柄;該句柄必須是已經(jīng)分配成功的句柄;
**bindpp——用戶定義的傳入值集合的指針;該參數(shù)指針從下標(biāo)0開始,依次遞增一個(gè)數(shù)組單元;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
position——需要綁定的該變量在陳述語(yǔ)句的列表中的位置,從1開始,依次遞增;
*valuep——需要綁定的傳入值的存儲(chǔ)地址;
value_sz——valuep參數(shù)的指向的存儲(chǔ)地址空間的長(zhǎng)度;
dty——需要綁定的變量的數(shù)據(jù)類型;SQLT_STR表示該變量是個(gè)字符串變量;SQLT_INT則表示該變量是個(gè)整型變量;
*indp——變量或數(shù)組指示器,默認(rèn)為0;
*alenp——變量或數(shù)組長(zhǎng)度指示器,默認(rèn)為0;
*rcodep——即將提取的變量的值指示器,默認(rèn)為0;
maxarr_len——dyt參數(shù)的最大可能取值的數(shù)目,在非PL/SQL語(yǔ)句中該差數(shù)無(wú)效果;默認(rèn)值為0;
*curelep——對(duì)應(yīng)與maxarr_len,表示dyt參數(shù)取值的實(shí)際數(shù)目;默認(rèn)值為0;
mode——變量提取模式。其取值為OCI_DEFAULT或OCI_DATA_AT_EXEC;當(dāng)使用OCI_DATA_AT_EXEC時(shí),value_sz表示在該陳述語(yǔ)句執(zhí)行過程中可以使用的傳入的該項(xiàng)值的最大存儲(chǔ)長(zhǎng)度,此時(shí)需要?jiǎng)討B(tài)綁定該傳入值;一般來(lái)說,mode的取值都為OCI_DEFAULT;
該函數(shù)使用舉例如下:OCIBindByPos(stmthp, &bndhp[3],
errhp, (ub4) 4,
(dvoid *) register_number,
(sb4) nLen, SQLT_STR,
(dvoid *) 0, (ub2 *)0,
(ub2 *)0,
(ub4) 0, (ub4 *) 0,
(ub4) OCI_DEFAULT)
函數(shù)原型:sword OCIBindByName ( OCIStmt *stmtp,
OCIBind **bindpp,
OCIError *errhp,
CONST text *placeholder,
sb4 placeh_len,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *alenp,
ub2 *rcodep,
ub4 maxarr_len,
ub4 *curelep,
ub4 mode )
參數(shù)說明:
*stmtp——用以進(jìn)行查詢的陳述語(yǔ)句句柄;該句柄必須是已經(jīng)分配成功的句柄;
**bindpp——用戶定義的傳入值集合的指針;該參數(shù)指針從下標(biāo)0開始,依次遞增一個(gè)數(shù)組單元;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
*placeholder——需要綁定的該變量在陳述語(yǔ)句中的占位符;
placeh_len——palceholder參數(shù)的長(zhǎng)度;
*valuep——指向需要綁定的該變量的傳入值的地址;
value_sz——valuep參數(shù)存儲(chǔ)的變量值的位組長(zhǎng)度;
dty——需要綁定的變量的數(shù)據(jù)類型;SQLT_STR表示該變量是個(gè)字符串變量;SQLT_INT則表示該變量是個(gè)整型變量;
*indp——變量或數(shù)組指示器,默認(rèn)為0;
*alenp——變量或數(shù)組長(zhǎng)度指示器,默認(rèn)為0;
*rcodep——即將提取的變量的值指示器,默認(rèn)為0;
maxarr_len——dyt參數(shù)的最大可能取值的數(shù)目,在非PL/SQL語(yǔ)句中該差數(shù)無(wú)效果;默認(rèn)值為0;
*curelep——對(duì)應(yīng)與maxarr_len,表示dyt參數(shù)取值的實(shí)際數(shù)目;默認(rèn)值為0;
mode——變量提取模式。其取值為OCI_DEFAULT或OCI_DATA_AT_EXEC;當(dāng)使用OCI_DATA_AT_EXEC時(shí),value_sz表示在該陳述語(yǔ)句執(zhí)行過程中可以使用的傳入的該項(xiàng)值的最大存儲(chǔ)長(zhǎng)度,此時(shí)需要?jiǎng)討B(tài)綁定該傳入值;一般來(lái)說,mode的取值都為OCI_DEFAULT;
該函數(shù)使用舉例如下:OCIBindByName(stmthp, &bndhp[1],
errhp,
(text *) ":field1",
(sb4) strlen((char *)
":phone_number"),
(dvoid *) & to_field1,
(sb4) sizeof(phone_number),
SQLT_STR,
(dvoid *) 0, (ub2 *)0,
(ub2 *)0,(ub4) 0, (ub4 *) 0,
(ub4) OCI_DEFAULT)
補(bǔ)充說明:如果輸入變量是多行資料,則valuep參數(shù)應(yīng)該為一個(gè)用戶定義了大小的靜態(tài)數(shù)組的初始地址,其大小為輸入變量的行數(shù)與該變量自身大小的乘積。此時(shí),在函數(shù)后面還需要使用另一個(gè)函數(shù)OCIBindArrayOfStruct來(lái)定義該數(shù)組。函數(shù)OCIBindArrayOfStruct說明如下:
函數(shù)原型:sword OCIBindArrayOfStruct ( OCIBind *bindp,
OCIError *errhp,
ub4 pvskip,
ub4 indskip,
ub4 alskip,
ub4 rcskip )
參數(shù)說明:
*bindp——從函數(shù)OCIBindByPos或OCIBindByName返回的對(duì)應(yīng)該變量的綁定句柄,對(duì)應(yīng)于函數(shù)OCIBindByPos或OCIBindByName的第二項(xiàng)參數(shù)bindpp;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
pvskip——從本條記錄中該變量的存儲(chǔ)地址的到下條記錄中該變量的存儲(chǔ)地址之間的大小;也就是定義的一條記錄的存儲(chǔ)空間的大小;
indskip——默認(rèn)為0;
rlskip——默認(rèn)為0;
rcskip——默認(rèn)為0;
該函數(shù)使用舉例如下:OCIBindArrayOfStruct(bndhp[N],
errhp,
sizeof(record_array[0]),
indsk[N],
rlsk[N],
rcsk[N])
十、 執(zhí)行陳述語(yǔ)句。
在執(zhí)行語(yǔ)句分析完成,并且變量定義或綁定完成后,便可以執(zhí)行該陳述句柄,從而實(shí)現(xiàn)陳述語(yǔ)句中的SQL語(yǔ)句能完成的功能。使用函數(shù)OCIStmtExecute來(lái)執(zhí)行該陳述句柄。執(zhí)行成功,返回0;
函數(shù)原型:sword OCIStmtExecute ( OCISvcCtx *svchp,
OCIStmt *stmtp,
OCIError *errhp,
ub4 iters,
ub4 rowoff,
CONST OCISnapshot *snap_in,
OCISnapshot *snap_out,
ub4 mode)
參數(shù)說明:
*svchp——已分配并設(shè)置成功的服務(wù)句柄;
*stmtp——指向需要執(zhí)行的陳述語(yǔ)句的句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
iters——對(duì)于非選擇語(yǔ)句來(lái)說,該函數(shù)執(zhí)行次數(shù)等于iters減去rowoff的值;對(duì)于選擇語(yǔ)句來(lái)說,如果iters不為0,則該函數(shù)在執(zhí)行前必須有定義句柄(即需要定義位址空間來(lái)存儲(chǔ)select出來(lái)的變量值),而函數(shù)會(huì)預(yù)先提取出多于iters條記錄(如果可提取記錄條數(shù)大于iters的話),將其中iters條正式提取出來(lái);如果事先并不知道有多少條記錄會(huì)被提取,則將iters的值置為0;在非選擇語(yǔ)句中,若iters的值為0,則函數(shù)返回錯(cuò)誤;
rowoff——函數(shù)執(zhí)行時(shí),輸入變量在綁定的變量數(shù)組的開始位置。用于多行記錄的修改或插入、刪除;比如,定義的綁定變量為array[100],執(zhí)行該函數(shù)時(shí),iters的值為50,rowoff的值為10,則表示從array[10]開始提取傳入值,而執(zhí)行的次數(shù)則是50-10
= 40(次);
*snap_in——可選參數(shù)。默認(rèn)值為0;
*snap_out——可選參數(shù)。默認(rèn)值為0;
mode——執(zhí)行模式;有四種執(zhí)行模式:
OCI_DEFAULT——缺省模式,在該模式下,總是隱式返回選擇選擇語(yǔ)句的有關(guān)描述信息;
OCI_DESCRIBE_ONLY——在該模式下,陳述句柄并不被執(zhí)行,但是它會(huì)返回可提取記錄的條數(shù);
OCI_COMMIT_ON_SUCCESS——在該模式下,如若函數(shù)執(zhí)行成功,則當(dāng)前的處理馬上會(huì)自動(dòng)提交;
OCI_EXACT_FETCH——該模式用于當(dāng)前程序很明確的清楚有多少條記錄會(huì)被提取出來(lái);并且,使用該模式前必須要有定義句柄;
該函數(shù)的使用舉例如下:OCIStmtExecute(svchp, stmthp, errhp,
(ub4) nCount, (ub4) 0,
(CONST OCISnapshot*) 0,
(OCISnapshot*) 0,
(ub4) OCI_DEFAULT)
另外,還可以使用函數(shù)OCIStmtFetch來(lái)提取固定數(shù)目的記錄,其函數(shù)使用說明如下:
函數(shù)原型:sword OCIStmtFetch ( OCIStmt *stmtp,
OCIError *errhp,
ub4 nrows,
ub2 orientation,
ub4 mode )
參數(shù)說明:
*stmtp——需要執(zhí)行的陳述句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
nrows——需要提取的記錄的條數(shù);
orientation——該參數(shù)只有唯一一個(gè)缺省值:OCI_FETCH_NEXT;
mode——默認(rèn)為OCI_DEFAULT;
該函數(shù)使用舉例如下:sword OCIStmtFetch (stmtp,
errhp,
rows_number,
OCI_FETCH_NEXT,
OCI_DEFAULT)
該函數(shù)成功執(zhí)行,而無(wú)數(shù)據(jù)時(shí),返回OCI_NO_DATA;
十一、事務(wù)提交。
在執(zhí)行陳述句柄后,有的語(yǔ)句如insert、delete等需要提交當(dāng)前事務(wù),從而真正實(shí)現(xiàn)insert、delete等功能。OCI8使用函數(shù)OCITransCommit來(lái)實(shí)現(xiàn)這一功能。
函數(shù)原型:sword OCITransCommit ( OCISvcCtx *svchp,
OCIError *errhp,
ub4 flags )
參數(shù)說明:
*svchp——已分配并設(shè)置成功的服務(wù)句柄;其值等于于OCIStmtExecute函數(shù)的srchp參數(shù)值。
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
flags——提交標(biāo)志。默認(rèn)為0;
該函數(shù)使用舉例如下:OCITransCommit(svchp, errhp, (ub4) 0)
十二、事務(wù)回滾。
在執(zhí)行完陳述語(yǔ)句后,若需要取消當(dāng)前執(zhí)行的操作,則需要回滾當(dāng)前事務(wù)。OCI8使用函數(shù)OCITransRollback來(lái)完成該功能。
函數(shù)原型:sword OCITransRollback(dvoid *svchp,
OCIError *errhp,
ub4 flags )
參數(shù)說明:
*svchp——需要回滾當(dāng)前事務(wù)的服務(wù)句柄;其值等于于OCIStmtExecute函數(shù)的srchp參數(shù)值。
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
flags——回滾標(biāo)志。目前只有一個(gè)唯一的取值得:OCI_DEFAULT;
該函數(shù)使用舉例如下:OCITransRollback(svchp,
errhp,
OCI_DEFAULT)
十三、斷開與數(shù)據(jù)庫(kù)的連接
斷開與數(shù)據(jù)庫(kù)的連接需要進(jìn)行下面一系列工作:結(jié)束當(dāng)前會(huì)話、斷開與數(shù)據(jù)庫(kù)連接服務(wù)、釋放分配的各個(gè)句柄。下面分別說明各項(xiàng)工作所使用的oci函數(shù)。
結(jié)束當(dāng)前會(huì)話:如果要斷開與數(shù)據(jù)庫(kù)的連接,則需要先結(jié)束當(dāng)前會(huì)話,使用函數(shù)OCISessionEnd來(lái)完成該功能。執(zhí)行成功,返回0
函數(shù)原型:sword OCISessionEnd(OCISvcCtx *svchp,
OCIError *errhp,
OCISession *authp,
ub4 mode)
參數(shù)說明:
*svchp——需要斷開的服務(wù)句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
*authp——會(huì)話句柄;
mode——會(huì)話結(jié)束模式。目前只有一種模式:OCI_DEFAULT;
該函數(shù)使用舉例如下:OCISessionEnd(svchp,
errhp,
authp,
(ub4) 0)
斷開與數(shù)據(jù)庫(kù)的連接服務(wù):當(dāng)前會(huì)話結(jié)束后,需要斷開與服務(wù)器的連接,結(jié)束用戶對(duì)數(shù)據(jù)庫(kù)的操作。OCI8使用函數(shù)OCIServerDetach來(lái)完成該任務(wù)。執(zhí)行成功,返回0;
函數(shù)原型:sword OCIServerDetach(OCIServer *srvhp,
OCIError *errhp,
ub4 mode )
參數(shù)說明:
*svchp——需要斷開的服務(wù)器句柄;
*errhp——已分配成功的錯(cuò)誤類型句柄;若該函數(shù)執(zhí)行出錯(cuò),則該參數(shù)承載出錯(cuò)的原因;
mode——執(zhí)行模式,目前只有一種模式:OCI_DEFAULT;
該函數(shù)使用舉例如下:OCIServerDetach(srvhp,
errhp,
(ub4) OCI_DEFAULT)
釋放分配的各個(gè)句柄:在結(jié)束當(dāng)前會(huì)話、斷開與數(shù)據(jù)庫(kù)的連接后,由于我們手動(dòng)分配了很多句柄,系統(tǒng)不會(huì)自動(dòng)釋放,因而需要手工釋放這些句柄,清掃使用環(huán)境。OCI8里,使用函數(shù)OCIHandleFree來(lái)釋放各個(gè)句柄。
函數(shù)原型:sword OCIHandleFree(dvoid *hndlp,ub4 type)
參數(shù)說明:
*hndlp——需要釋放的句柄;
type——該句柄的類型。參見OCIHandleAlloc函數(shù)說明的type參數(shù);
注:使用OCIHandleAlloc函數(shù)分配了哪些句柄,那么就需要用該函數(shù)釋一一放這些句柄;
附錄:使用OCI8函數(shù)與數(shù)據(jù)庫(kù)交互大致步驟
一、定義并初始化所需各變量
envhp、srvhp、errhp、svchp、authp、hndlp、stmthp、等等
二、連接數(shù)據(jù)庫(kù)
1、 OCIInitialize。初始化OCI程序環(huán)境
2、 OCIEnvInit。 初始化OCI環(huán)境句柄
3、 OCIHandleAlloc。分配各句柄,需要分配的句柄類型如下:
OCI_HTYPE_SVCCTX,
OCI_HTYPE_ERROR,
OCI_HTYPE_SESSION,
OCI_HTYPE_SERVER,
4、 OCIServerAttach。指定資料源路徑
5、 OCIAttrSet。設(shè)置各項(xiàng)參數(shù)。需要設(shè)置的參數(shù)類型如下:
OCI_ATTR_SERVER 使用的句柄型為OOCI_HTYPE_SVCCTX
OCI_ATTR_USERNAME
OCI_ATTR_PASSWORD
上面兩個(gè)參數(shù)使用的句柄類型為OCI_HTYPE_SESSION
6、 OCISessionBegin。創(chuàng)建并開始會(huì)話
7、 OCIAttrSet。設(shè)置會(huì)話參數(shù)類型OCI_ATTR_SESSION,使用句柄為OCI_HTYPE_SVCCTX
8、 OCIHandleAlloc。分配OCI_HTYPE_STMT型陳述句柄
三、操作數(shù)據(jù)庫(kù)
1、OCIStmtPrepare。準(zhǔn)備事件處理
2、OCIBindByPos、OCIBindByName(OCIDefineByPos)綁定(定義)變量。如果是多行資料,則需要使用
OCIBindArrayOfStruct(OCIDefineArrayOfStruct)函數(shù)來(lái)綁定(定義)存放該數(shù)據(jù)的數(shù)組
3、OCIStmtExecute。執(zhí)行SQL語(yǔ)句
4、OCITransCommit(OCITransRollback)。提交(回滾)當(dāng)前事務(wù)
四、斷開數(shù)據(jù)庫(kù)
1、OCISessionEnd。結(jié)束會(huì)話
2、OCIServerDetach。斷開與服務(wù)器的連接
3、OCIHandleFree。釋放已分配的各句柄。需要釋放的句柄如下:
OCI_HTYPE_SVCCTX,
OCI_HTYPE_ERROR,
OCI_HTYPE_SESSION,
OCI_HTYPE_SERVER,
OCI_HTYPE_STMT
OCI_HTYPE_ENV
五、提取出錯(cuò)描述信息
1、OCIErrorGet。上述各函數(shù)若執(zhí)行失敗,都可以使用該函數(shù)來(lái)提取出錯(cuò)信息的ORCALE描述。
總結(jié)
以上是生活随笔為你收集整理的pro c 访问 MySQL_Pro*C OCI OCCI 及OCI介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SlickEdit基本设置
- 下一篇: MySQL InnoDB 是如何存储数据