Oracle Database Development (7). The thinking of the OCI example .
Vert Melon
Jun 26,2007
The central content in this article is about the common operations with Oracle . Just
follow the instructions and enrich the relevant knowledge by the OCI official document .
I'd like to copy many sentences from OCI official document . It would save me many
trouble and these sentences are more exactly .
1. Connection
Connection is surely a first step done with the database . OCI provides two mode of
connection , which is Single User, Single Connection and Multiple Sessions or Connections.
The example also gave the both implement .
a. Single User, Single Connection
-----------------------------------------------------------------------------
An application maintains only a single user session for each database connection
at any time .
The corresponding functions in the example listed as follows :
OCIDB::Single_Conn()
OCIDB::Single_Disc()
The calling order of routines :
OCIEnvCreate
OCIHandleAlloc <ERROR>
OCILogon
OCILogoff
OCIHandleFree <ERROR>
OCIHandleFree <ENV>
An application of OCI must have one environment handle , which is created by OCIEnvCreate()
here . The environment handle defines a context in which all OCI functions are invoked .
It is the base of almost all of the other handles which would be seen in future.
OCIEnvCreate() creates and initializes an environment for OCI functions to work under .
This call should be invoked before any other OCI call and should be used instead of
the OCIInitialize() and OCIEnvInit() calls. OCIInitialize() and OCIEnvInit() calls will be
supported for backward compatibility. But if you are writing a DLL or a shared library
using OCI library then this call should definitely be used instead of OCIInitialize() and
OCIEnvInit() call . OCIInitialize() and OCIEnvInit() call is used in OCIDB::Multiple_Conn() ,
we'll cover it soon.
Almost all OCI calls include in their parameter list one or more handles. A handle is an
opaque pointer to a storage area allocated by the OCI library. You use a handle to store
context or connection information, (for example, an environment or service context handle),
or it may store information about OCI functions or data (for example, an error or describe
handle). Handles can make programming easier, because the library, rather than the application,
maintains this data.
Either OCIEnvCreate() or ( OCIInitialize() and OCIEnvInit() ) allocates a environment
handle . I defined a private member variable named m_pOCIEnv to store it . You can find
the both routines return a address as environment handle .
There is also a very important handle , which appears in mostly OCI calls . That is the
error handle .The error handle maintains information about errors that occur during an OCI
operation. If an error occurs in a call, the error handle can be passed to OCIErrorGet() to
obtain additional information about the error that occurred.
Go and look at OCIException::CheckError() which shows a integral error management .
After the preparation of Environment and Error , we will come to the actual code about
the connection . OCILogon() and OCILogoff() is quite easy to us . Notice that a service
context handle will be created during the time processing OCILogon().
A service context handle defines attributes that determine the operational context for
OCI calls to a server. The service context contains three handles as its attributes, that
represent a server connection, a user session, and a transaction. OCILogon() call also
implicitly allocates server and user session handles associated with the session.
Is is a very good custom that release the resource allocated at first in an order when
the program comes the end . OCIDB::Single_Disc() does it explicitly .
b. Multiple Sessions or Connections
-----------------------------------------------------------------------------
If an application needs to maintain multiple user sessions on a database connection,
the application requires a different set of calls to set up the sessions and connections.
The corresponding functions in the example listed as follows :
OCIDB::Multiple_Conn()
OCIDB::Multiple_Disc()
The calling order of routines :
OCIInitialize
OCIEnvInit
OCIHandleAlloc <Error>
OCIHandleAlloc <Server Context >
OCIHandleAlloc <Server>
OCIAttrSet <Set Server Into ServerContext>
OCIServerAttach <AttachServer>
OCIHandleAlloc <Session>
OCIAttrSet <Set Session Into ServerContext>
OCISessionBegin
...
Compare with OCILogon() it becomes more complex . Each handle is allocated by
hand here .
There is someting new . All OCI handles have attributes associated with them. These
attributes represent data stored in that handle. You can read handle attributes using the
attribute get call, OCIAttrGet(), and you can change them with the attribute set call,
OCIAttrSet(). OCIServerAttach() creates an access path to the data server for OCI
operations. OCISessionBegin() establishes a session for a user against a particular server.
This call is required for the user to be able to execute any operation on the server.
Notice that the calling order of OCIAttrSet() or OCIServerAttach() is random . As the
same , either call OCIAttrSet() before OCISessionBegin() or call OCISessionBegin()
before OCIAttrSet() is OK .
You can change the content of the file Main.cpp to implement the different operation .
Some code for test is listed below :
#include "OCIDB.h"
int main() {
OCIDB db;
db.Single_Conn();
db.Single_Disc();
}
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.Multiple_Disc();
}
2. Execute non-query SQL
Non-query SQL means that SQL doesn't return any data , such as create , insert , delete
and so on . These SQL statements also could be comprehanded as DDL . OCI also support
the bind for extern values and we will discuss it in next section. Please search the relevant
code in the example. The function OCIDB::ExecuteSql() covers it .
At first you should allocate a statement handle in the envionment handle. A statement
handle is the context that identifies a SQL or PL/SQL statement and its associated attributes.
Every SQL statement must be prepared for execution by OCIStmtPrepare() then. This is a
completely local call, requiring no round trip to the server. No association is made at this
point between the statement and a particular server.
After finished the steps above , call OCIStmtExecute() to execute the statement. For DDL
statements, no further steps are necessary.
You may use these code statements in Main.cpp as the following :
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.ExecuteSql("update liwei_test set id =123 where note='test' ");
db.Multiple_Disc();
}
3. Bind variable
Most DML statements, and some queries (such as those with a WHERE clause), require a
program to pass data to Oracle as part of a SQL or PL/SQL statement. Such data can be constant
or literal data, known when your program is compiled.
insert into liwei_test (id,name,note)values(1,'aABD','cadsf')
This statement is a simple one to insert some data known. When you prepare a SQL statement
or PL/SQL block that contains input data to be supplied at runtime, placeholders in the SQL statement
or PL/SQL block mark where data must be supplied. For example, the following SQL statement
contains three placeholders, indicated by the leading colons (for example, :id), that show where
input data must be supplied by the program.
insert into liwei_test (id,name,note)values(:id,:name,:note)
In this example I also made two different way using the bind . Look at this content of Main.cpp :
A. One-off bind with a predefine structure
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.BindAddVar(":id", 19809);
db.BindAddVar(":name", "liwei");
db.BindAddVar(":note", "test");
db.BindSql("insert into liwei_test (id,name,note)values(:id,:name,:note) ");
db.BindAddVar(":id", 169);
db.BindAddVar(":name", "sstem ch");
db.BindSql("insert into liwei_test (id,name)values(:id,:name) ");
db.Multiple_Disc();
}
OCIDB::BindAddVar() add the user parameters into the share variable which name
is m_BindVars . It has several overrided patterns .
OCIDB::BindSql() execute the SQL statement binding the structural variable . All of
the OCI operation needed is called in an order .
Notice : OCIDB::BindAddVar() allocates memory automaticly as the bind variable need .
B. Bind the variable step by step consistent with the defined order of OCI
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.UserPrepare("insert into liwei_test (id,name,note)values(:id,:name,:note)");
db.UserBind(":id",10701);
db.UserBind(":name", "liweitest");
db.UserBind(":note", "asdfasdf");
db.UserExecute();
db.UserCommit();
db.UserFree();
db.Multiple_Disc();
}
The process had been divided into several steps here . In this case you can extend some
further functions more easily .
Notice : The class function starts with "User" is a series which performs a common template .
Both the two methods above follow this calling order :
OCIHandleAlloc <stmt>
OCIStmtPrepare
OCIBindByName/OCIBindByPos
OCIStmtExecute
OCITransCommit/OCITransRollback
OCIHandleFree <stmt>
4. Get the Recordset from a SQL Select statement
In this section i'd like to introduce a simple query example about the select statement which
select-list cols is known before execution.
Query statements return data from the database to your application. When processing a query,
you must define an output variable or an array of output variables for each item in the select-list
from which you want to retrieve data.
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.UserSelect("select id,name,note,value from liwei_test where note='test'");
while(db.UserFetch()==0) {
printf("id:%f\n", db.UserGetFloat("id"));
printf("name:%s\n", db.UserGetString("name"));
printf("note:%s\n", db.UserGetString("note"));
printf("value:%f\n\n", db.UserGetFloat("value"));
}
db.UserSelectFree();
}
As you see , a simple one is gave now , which still seems a bit complex . Firstly i defined
a structure "TSelectVar" to store select-list . "TSelectVar" had a union to store values in
different type . Then i encapsuled the select operation into the four parts .
UserSelect
UserFetch
UserGet
UserSelectFree
So let's have a look at the first part -- OCIDB::UserSelect() .
OCIHandleAlloc() , OCIStmtPrepare(), OCIStmtExecute() and then the OCIAttrGet() !
I want to know the column count of the select-list , so used OCIAttrGet() there . For each
column , i called OCIParamGet() to get a OCI parameter and then used OCIAttrGet() to
fetch lots of useful imformation such as name, size, presision and so on .
After the get of attribute , you should define the content of the select-list using OCIDefineByPos()
or OCIDefineByName() then.
The purpose of these Get() and Define() calls is to describe the select-list for the following
action which is get . OCIDB::UserFetch() is easily comprehanded , for only one call OCIStmtFetch
in it .
Pay attention to the member function like OCIDB::UserGet , these functions is interface
to exterior user . It is overrided also .
int UserGetInt(int index);
int UserGetInt(char * name);
char * UserGetString(int index);
char * UserGetString(char * name);
float UserGetFloat(int index);
float UserGetFloat(char * name);
Peruse the code patiently and you will gain much knowledge .
5.The Last
This example is just for a demonstration or a accidence . You mush not stop here only .
Take this way for more info by practice and online help. Obviousely there are many points
which are not very standard in the article , for a exam i didn't use CONST while passing a
value . This is a important aspect to improve .
For you may not acclimatize youself to the variety of the OCI type , take it easy , try to
get together with the OCI Function Reference and force a type conversion .
-------------------------------------------------------------------------------------------------------
Oracle鏁版嵁搴撳紑鍙?涓?.OCI紺轟緥寮鍙戣鏄?/p>
鑽夋湪鐡?/p>
2007-6-26
榪欑瘒鏂囩珷鐨勪富瑕佸唴瀹規槸浠嬬粛鐨勫父瑙佺殑OCI鏁版嵁鎿嶄綔銆傚彲浠ラ『鐫鏂囩珷鎬濊礬緇撳悎OCI
鐩稿叧Oracle鏂囨。鍘葷悊瑙c傝繖閲屼粠鍘熸枃妗d腑澶嶅埗浜嗕笉灝戝師鍙ワ紝榪欎釜鐪佷簡寰堝楹葷儲鑰屼笖
榪欎簺琛ㄨ揪鏇翠負鍑嗙‘銆?/p>
涓銆佹暟鎹簱榪炴帴
鏁版嵁搴撹繛鎺ユ槸鎿嶄綔鏁版嵁搴撶殑絎竴姝ャ侽CI鎻愪緵浜嗕袱縐嶆ā寮忕殑榪炴帴錛屽嵆鍗曠敤鎴?br>鍗曡繛鎺ュ拰澶氱敤鎴峰榪炴帴銆傛垜榪欓噷鐨凮CI紺轟緥涔熷垎鍒彁渚涗簡涓ょ瀹炵幇鏂瑰紡銆?/p>
a.鍗曠敤鎴鳳紝鍗曡繛鎺?br> -----------------------------------------------------------------------------
搴旂敤紼嬪簭瀵逛簬鏌愪竴鏁版嵁搴撹繛鎺ヤ粎鏀寔鍗曠敤鎴瘋繘紼嬨?br>
渚嬪瓙涓搴旂殑鍑芥暟榪囩▼錛?br> OCIDB::Single_Conn()
OCIDB::Single_Disc()
OCI鍐呴儴榪囩▼鐨勮皟鐢ㄩ『搴忓涓嬶細
OCIEnvCreate
OCIHandleAlloc <ERROR>
OCILogon
OCILogoff
OCIHandleFree <ERROR>
OCIHandleFree <ENV>
OCI搴旂敤紼嬪簭蹇呴』鏈変竴涓幆澧冨彞鏌勶紝鍦ㄨ繖閲岀敱 OCIEnvCreate()鍒涘緩銆傜幆澧冨彞鏌勭浉褰?br>浜庡畾涔変竴涓鍣紝鍖呭惈浜嗕互鍚庣殑鎵鏈塐CI鍙ユ焺錛岃繖鏄疧CI璋冪敤鐨勫熀紜銆?br> OCIEnvCreate()鍒涘緩騫跺垵濮嬪寲浜嗕竴涓狾CI鍑芥暟鐨勫伐浣滅幆澧冿紝蹇呴』鍏堜簬鍏朵粬OCI鍑芥暟
涔嬪墠璋冪敤銆備竴鑸潵璇達紝浠庡吋瀹規ф柟闈㈣冭檻錛屾渶濂戒嬌鐢∣CIInitialize() 鍜?OCIEnvInit()鏇夸唬
OCIEnvCreate()銆備笉榪囧鏋滀綘鍦ㄥ啓dll鎴栬呭叡浜簱涔嬬被鐨勪笢瑗匡紝鏈濂借繕鏄敤OCIEnvCreate()銆?br>OCIDB::Multiple_Conn()涓氨浣跨敤浜哋CIInitialize()鍜孫CIEnvInit() 錛屾垜浠竴浼氫細鎻愬埌銆?br>
緇濆ぇ澶氭暟鐨凮CI璋冪敤閮戒嬌鐢ㄤ簡涓涓垨澶氫釜鍙ユ焺銆傚彞鏌勬寚鍚戠敱OCI搴撹嚜鍔ㄥ垎閰嶇殑鍐呭瓨
絀洪棿銆傚彲浠ュ瓨鍌ㄨ繛鎺ョ幆澧冧俊鎭?濡傦紝鏁版嵁搴撹繛鎺ョ幆澧冩垨鏈嶅姟鐜鍙ユ焺) 錛孫CI鍑芥暟鎵ц
榪囩▼涓浉鍏充俊鎭?濡傦紝閿欒鍙ユ焺鎴栬呮弿榪板彞鏌?銆侽CI鍙ユ焺璁╁紑鍙戝伐浣滃彉寰楃畝鍗曡搗鏉ワ紝
榪欎簺鐩稿叧淇℃伅鏄敱OCI搴撴墍綆$悊錛岃屼笉鏄敤鎴風殑搴旂敤紼嬪簭銆?/p>
涓嶇鏄疧CIEnvCreate()榪樻槸(OCIInitialize()鍜孫CIEnvInit())閮藉垎閰嶄簡涓涓暟鎹簱鐜鍙?br>鏌勩傛垜榪欓噷瀹氫箟浜嗙鏈夋垚鍛樺彉閲弇_pOCIEnv鐢ㄦ潵瀛樺偍鐜鍙ユ焺銆?/p>
OCI涓繕鏈変竴涓緢閲嶈鐨勫彞鏌勶紝緇忓父鍑虹幇鍦∣CI璋冪敤榪囩▼涓傝繖灝辨槸閿欒鍙ユ焺銆傞敊璇?br>鍙ユ焺綆$悊鍦∣CI鏁版嵁鎿嶄綔涓嚭鐜扮殑鍚勭被閿欒錛屽鏋滃湪璋冪敤涓嚭閿欙紝鍙互鎶婇敊璇彞鏌?br>浼犻掔粰OCIErrorGet()鏉ヨ幏鍙栨洿澶氱殑閿欒淇℃伅銆?br> OCIException::CheckError() 鏄竴涓畬鏁寸殑閿欒澶勭悊紺轟緥銆?br>
鍑嗗濂界幆澧冨彞鏌勫拰閿欒鍙ユ焺鍚庯紝璇ュ埌鏁版嵁搴撹繛鎺ョ殑瀹為檯浠g爜浜嗐傝繖閲岀殑OCILogon()
鍜?OCILogoff() 鐞嗚В璧鋒潵騫朵笉闅俱傝娉ㄦ剰OCILogon()鎵ц榪囩▼涓繑鍥炰簡涓涓湇鍔$幆澧?br>鍙ユ焺銆?br> 鏈嶅姟鐜鍙ユ焺瀹氫箟涓浜涢噸瑕佸睘鎬э紝鐩存帴鍐沖畾浜嗚繛鎺ユ暟鎹簱鐨勬柟寮忔柟娉曘傛湇鍔$幆澧?br>鍙ユ焺鍖呭惈涓変釜灞炴э紝鍏跺疄灝辨槸鍙﹀鐙珛鐨勪笁涓彞鏌勶紝鍗蟲湇鍔¤繛鎺ワ紝鐢ㄦ埛浼氳瘽鍜屼簨鍔°?br> OCILogon()鎵ц榪囩▼涓叾瀹炰篃澹版槑浜嗘湇鍔¤繛鎺ュ拰鐢ㄦ埛浼氳瘽鐨勭浉鍏沖彞鏌勶紝鍙笉榪囨槸闅?br>寮忓0鏄庛?/p>
鍦ㄧ▼搴忕粨鏉熸椂鎵嬪伐閲婃斁璧勬簮鏄緢濂界殑涔犳儻錛屽彲鍙傝OCIDB::Single_Disc()銆?br>
b.澶氱敤鎴鳳紝澶氳繛鎺?br> -----------------------------------------------------------------------------
濡傛灉搴旂敤紼嬪簭瀵瑰崟涓鏁版嵁搴撹繛鎺ラ渶瑕佺淮鎶ゅ涓敤鎴蜂細璇濓紝灝遍渶瑕佷嬌鐢ㄥ彟涓縐嶆柟寮忎簡銆?br>
渚嬪瓙涓搴旂殑鍑芥暟榪囩▼錛?br> OCIDB::Multiple_Conn()
OCIDB::Multiple_Disc()
OCI鍐呴儴榪囩▼鐨勮皟鐢ㄩ『搴忓涓嬶細
OCIInitialize
OCIEnvInit
OCIHandleAlloc <Error>
OCIHandleAlloc <Server Context >
OCIHandleAlloc <Server>
OCIAttrSet <Set Server Into ServerContext>
OCIServerAttach <AttachServer>
OCIHandleAlloc <Session>
OCIAttrSet <Set Session Into ServerContext>
OCISessionBegin
...
涓嶰CILogon()鐩告瘮錛屽彉鐨勬湁浜涘鏉傦紝姣忎釜鍙ユ焺鍦ㄨ繖閲岄兘鏄墜宸ュ幓鍒涘緩銆傞渶瑕佹彁鍑?br>鐨勬槸錛屾墍鏈夌殑OCI鍙ユ焺閮芥湁鍏剁浉鍏沖睘鎬э紝榪欎簺灞炴у瓨鍌ㄤ簡涓浜涙湁鐢ㄧ殑鏁版嵁銆傚彲浠ヤ嬌
鐢∣CIAttrGet()鑾峰彇瀵瑰簲淇℃伅錛屼篃鍙互閫氳繃OCIAttrSet()榪涜淇敼銆侽CIServerAttach()
鍒涘緩浜嗕竴涓狾CI鎿嶄綔鐨勬暟鎹湇鍔¤闂礬寰勶紝OCISessionBegin() 紜珛鐢ㄦ埛浼氳瘽榪炴帴銆?br>榪欓噷瀹屾垚鍚庯紝鎵嶅彲浠ヨ繘琛屽疄闄呯殑鏁版嵁鎿嶄綔銆?br> 娉ㄦ剰榪欓噷鐨凮CIAttrSet()鍜孫CIServerAttach()鐨勮皟鐢ㄩ『搴忎笉鏄浐瀹氱殑錛岀被浼肩殑 OCISessionBegin()
鍜?OCIAttrSet() 鍏堝悗欏哄簭涔熸槸鍙互浜掓崲鐨勩?/p>
浣犲彲浠ヨ嚜琛屾洿鏀筂ain.cpp鍐呭浠ュ畬鎴愪笉鍚岀殑鏁版嵁鎿嶄綔銆?br>
#include "OCIDB.h"
int main() {
OCIDB db;
db.Single_Conn();
db.Single_Disc();
}
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.Multiple_Disc();
}
浜屻佹墽琛屾棤榪斿洖鍊肩殑SQL璇彞
榪欑被璇彞涓鑸寘鎷琧reate , insert鍜宒elete絳夌瓑錛屾棤榪斿洖鍊艱鍙ヤ竴鑸篃鍙互鐞嗚В涓篋DL
璇彞銆侽CI涔熸敮鎸佸SQL璇彞榪涜鍙橀噺緇戝畾錛屼笅鑺備細涓撻棬璁ㄨ銆?br> 渚嬪瓙涓浉鍏崇殑鍑芥暟鏄疧CIDB::ExecuteSql() 銆?br>
棣栧厛浣犻渶瑕佸湪鐜鍙ユ焺涓0鏄庝竴涓鍙ュ彞鏌勩傝鍙ュ彞鏌勫寘鍚簡SQL鎴栬匬L/SQL
璇彞鍙婂叾鐩稿叧灞炴э紝姣忎釜SQL璇彞鍦ㄦ墽琛屽墠蹇呴』瑕佷嬌鐢∣CIStmtPrepare()榪涜棰勫鐞嗐?br>榪欎釜鏄湰鍦板寲璋冪敤錛屼笉浼氬悜鏈嶅姟鍣ㄧ鍙戦佽姹傘?/p>
瀹屾垚涓婇潰姝ラ鍚庯紝灝卞彲浠ヨ皟鐢∣CIStmtExecute() 鎵цSQL璇彞浜嗐?br>
浠g爜璇彞濡備笅錛?br>
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.ExecuteSql("update liwei_test set id =123 where note='test' ");
db.Multiple_Disc();
}
涓夈佸彉閲忕粦瀹?/p>
澶у鏁癉ML璇彞鎴栬呬竴浜涙煡璇?甯here鏉′歡鐨?闇瑕佸悜SQL浼犻掍竴浜涙暟鎹紝涓嬮潰鐨勪緥瀛?br>鏄湪紼嬪簭緙栬瘧鏃跺氨宸茬粡鐭ラ亾瑕佷紶閫掔殑鏁板箋?/p>
insert into liwei_test (id,name,note)values(1,'aABD','cadsf')
榪欐槸涓畝鍗曠殑渚嬪瓙錛屽綋棰勫鐞嗕竴涓猄QL璇彞鎴栬匬L/SQL鍧楋紝鍏朵腑鏈変簺鏁板兼槸闇瑕佸湪榪?br>琛屼腑鎵嶈兘紜畾鐨勩傝繖鏃跺氨闇瑕佸湪榪愯鍔ㄦ佸幓緇戝畾鍙橀噺浜嗭紝鎴戜滑鍦⊿QL璇彞鎴栬匬L/SQL鍧?br>涓嬌鐢?id涔嬬被鐨勭鍙鳳紝琛ㄧず鍙互鍋氫負鍙橀噺緇戝畾銆傚錛?/p>
insert into liwei_test (id,name,note)values(:id,:name,:note)
榪欎釜渚嬪瓙涓紝鎴戜嬌鐢ㄤ簡涓ょ閫斿緞鏉ョ粦瀹氬彉閲忋?br>
A.閫氳繃棰勫畾涔夌殑緇撴瀯浣撲竴嬈℃х粦瀹?br>
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.BindAddVar(":id", 19809);
db.BindAddVar(":name", "liwei");
db.BindAddVar(":note", "test");
db.BindSql("insert into liwei_test (id,name,note)values(:id,:name,:note) ");
db.BindAddVar(":id", 169);
db.BindAddVar(":name", "sstem ch");
db.BindSql("insert into liwei_test (id,name)values(:id,:name) ");
db.Multiple_Disc();
}
OCIDB::BindAddVar() 灝嗙浉鍏崇殑鐢ㄦ埛鍙橀噺鍙傛暟娣誨姞鍒癿_BindVars鍙橀噺涓紝榪欎釜鍑芥暟
鏈変笉鍚岀殑閲嶈澆褰㈠紡銆?br> OCIDB::BindSql() 緇戝畾緇撴瀯浣撳畾涔夌殑鍙橀噺錛屽茍鎵цSQL璇彞銆?br>
娉ㄦ剰錛歄CIDB::BindAddVar() 鏍規嵁緇戝畾鐨勫彉閲忓艱嚜鍔ㄥ垎閰嶅唴瀛?br>
B. 鏍規嵁OCI鍐呴儴欏哄簭涓姝ヤ竴姝ョ粦瀹?br>
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.UserPrepare("insert into liwei_test (id,name,note)values(:id,:name,:note)");
db.UserBind(":id",10701);
db.UserBind(":name", "liweitest");
db.UserBind(":note", "asdfasdf");
db.UserExecute();
db.UserCommit();
db.UserFree();
db.Multiple_Disc();
}
榪欓噷鎶婃暣涓繃紼嬪垝鍒嗘垚澶氭錛屽彲浠ユ柟渚夸互鍚庢墿灞曞姛鑳姐?br>
娉ㄦ剰錛歎ser鎵撳ご鐨勮繖浜涚郴鍒楀嚱鏁幫紝鍏跺疄鏄瘮杈冨父鐢ㄧ殑涓濂楁ā鏉褲?br>
榪欎袱縐嶆柟寮忚皟鐢∣CI鍐呴儴鍑芥暟鐨勯『搴忛兘鏄竴鏍風殑錛?br>
OCIHandleAlloc <stmt>
OCIStmtPrepare
OCIBindByName/OCIBindByPos
OCIStmtExecute
OCITransCommit/OCITransRollback
OCIHandleFree <stmt>s
鍥涖佷粠Select璇彞鑾峰彇璁板綍闆?/p>
榪欒妭涓昏浠嬬粛涓涓畝鍗曠殑鏌ヨ渚嬪瓙錛屼緥瀛愪腑鐨勬煡璇㈠垪鍦ㄦ墽琛屽墠宸茬粡鐭ラ亾銆?br> 鏌ヨ璇彞榪斿洖鏁版嵁搴撲腑鎵闇鏁版嵁錛屾墽琛屾煡璇㈡椂蹇呴』瑕佸畾涔夊閮ㄧ殑杈撳嚭鍙橀噺鎴栬呭彉
閲忔暟緇勬潵瀛樺偍浣犳墍闇瑕佹绱㈢殑鏁版嵁銆?/p>
#include "OCIDB.h"
int main() {
OCIDB db;
db.Multiple_Conn();
db.UserSelect("select id,name,note,value from liwei_test where note='test'");
while(db.UserFetch()==0) {
printf("id:%f\n", db.UserGetFloat("id"));
printf("name:%s\n", db.UserGetString("name"));
printf("note:%s\n", db.UserGetString("note"));
printf("value:%f\n\n", db.UserGetFloat("value"));
}
db.UserSelectFree();
}
涓婇潰灝辨槸涓涓皬渚嬪瓙銆傞鍏堟垜鍏堝畾涔変簡涓涓粨鏋勪綋TSelectVar(涓庣粦瀹氬彉閲忕殑緇撴瀯浣?br>綾諱技)鍑嗗瀛樺偍榪斿洖鐨勭粨鏋滈泦銆俆SelectVar 涓嬌鐢ㄤ簡Union瀛樺偍涓嶅悓綾誨瀷鐨勬暟鍊箋傜劧鍚?br>鎴戞妸鏁翠釜OCI Select榪囩▼灝佽鎴愬涓嬪洓閮ㄥ垎錛?br>
UserSelect
UserFetch
UserGet
UserSelectFree
鎴戜滑鍏堢湅絎竴閮ㄥ垎 OCIDB::UserSelect() 銆?br> OCIHandleAlloc() , OCIStmtPrepare(), OCIStmtExecute() 鐒跺悗鏄疧CIAttrGet() 銆?br> OCIAttrGet()涓昏鏄負浜嗚幏鍙栬繑鍥炵粨鏋滈泦鐨勫垪鏁般傚浜庢瘡涓鍒楋紝浣跨敤浜哋CIParamGet()
鍏堣幏鍙栨暣鍒楃殑OCIParm錛岀劧鍚庡啀浣跨敤OCIAttrGet()渚濇鑾峰彇璞″垪鍚嶏紝鍒楀ぇ灝忥紝綺懼害絳?br> 鏈夌敤鐨勪俊鎭?br>
鑾峰彇榪欎簺灞炴у悗錛屽氨闇瑕佽皟鐢∣CIDefineByPos()鎴朞CIDefineByName涓虹粨鏋滈泦瀹氫箟
鍐呭浜嗐?br>
鍏跺疄榪欎簺Get()鍜孌efine()灝辨槸涓轟簡鎻忚堪Select鎵ц鍚庤繑鍥炵殑緇撴灉闆嗭紝鏂逛究鎴戜滑鑾峰彇鍏朵腑
鏁版嵁銆侽CIDB::UserFetch() 閲岄潰鍙湁涓狾CIStmtFetch()錛屾瘮杈冨ソ鐞嗚В錛岃鐧戒簡灝辨槸鎺у埗
娓告爣銆?br>
娉ㄦ剰璞CIDB::UserGet鐨勮繖浜涗釜鎴愬憳鍑芥暟錛屾槸瀵瑰鐨勬暟鎹帴鍙o紝浠ヤ笅鏄笉鍚岀殑閲嶈澆褰?br> 寮忥細
int UserGetInt(int index);
int UserGetInt(char * name);
char * UserGetString(int index);
char * UserGetString(char * name);
float UserGetFloat(int index);
float UserGetFloat(char * name);
榪欓噷娌℃湁浠涔堝ソ璇寸殑錛岃璇諱唬鐮佸氨浼氭竻妤氥?br>
浜斻佸啓鍦ㄦ渶鍚?/p>
榪欎釜渚嬩粎鍋氭紨紺恒備笉榪囦笉蹇呬粎鍋滅暀浜庢錛屽瑕佹彁楂橈紝緇撳悎鍦ㄧ嚎鏂囨。澶氱粌鍗沖彲銆?br>榪欎釜渚嬪瓙鐨勪唬鐮佸湪鏌愪簺鏂歸潰鏄劇劧涓嶅瑙勮寖錛屽鏈湪浼犲間腑浣跨敤const錛岃繖涔熸槸浠ュ悗
瑕佹彁楂樼殑鏂歸潰銆?br> 鍙﹀錛屽垰鎺ヨЕOCI鏃訛紝鍙兘浼氬鍐呴儴鐨勪竴鍫嗙被鍨嬩笉澶傚簲錛岃繖閲屽鐪嬬湅鍑芥暟鐨勫弬鑰冿紝
灝介噺鍋氫竴浜涘己鍒舵х殑杞崲銆?nbsp;
Oracle Database Development (6). A first exploration of OCI
Vert Melon
Jun 25,2007
1.Preface
Last time , i provided a full example of OCI , which contains the actual code of connection
and SQL . Certainly it could not cover all of the knowledge , but i think it is a good beginning
for the fresher .
As the same as Pro*C you might confirm that you have installed it correctly . Look at this
paths as follows :
Windows : $ORACLE_HOME\oci
Linux/Unix : $ORACLE_HOME/rdbms/demo
There are many examples offered by ORACLE . Though it seems like a clutter , you also
can get some useful imformation .
The main platform we use here is Linux . And the Windows ? How can i config it in Windows ?
It would be a comfy thing if you have read the chapters recorded in <Oracle Database Development (1). Config OCI In Windows> .
It is easily comprehend by analogy .
2.Something you should know
What is the Oracle Call Interface?
The Oracle Call Interface (OCI) is a set of low-level APIs (Application Programming Interface Calls)
used to interact with Oracle databases. It allows one to use operations like logon, execute,
parse, fetch, etc. OCI programs are normally written in C or C++, although they can be written
in almost any programing language. Unlike with the Oracle Precompilers (like Pro*C and Pro*COBOL),
OCI programs are not precompiled.
Also I have found a official explaination about the choice between Pro*C and OCI .
Should one use OCI or the Oracle Precompilers?
OCI is superior to Pro*C in the following ways:
Performance is much better with OCI
Reduced code size
Direct access to built-in functions (No intermediate files or substitutions).
Piecewise Operation on LONG fields (All LONG field problems are solved)
In Pro*C one cannot dynamically allocate memory to be used as bind variables
You cannot control the Pro*C precompiler to provide better and more compilable C-code.
...
Common problems with OCI:
OCI code is difficult to write and to maintain
Very few people can write, let alone maintain OCI code
...
An OCI application program must do the following:
Connect to one or more databases: call the OCILogon (olog, olon or orlon) routines
Open the cursors needed by the program: use oexec, oexn, ofen or oftech calls.
Process the SQL statements that are needed to perform the application's tasks.
Close the cursors using the oclose routine.
Disconnect from the databases: use ologoff to close an open connection to oracle.
3.Obsolescent OCI Routines
After get through the section "Something you should know" , you may find some strange
words : oexec , ologoff or oclose . There are old routines in preceding release .
Release 8.0 of the Oracle Call Interface introduced an entirely new set of functions which
were not available in release 7.3. Release 8.1 added more new functions. Oracle9i OCI continues
to support these new functions, and adds more new calls. The earlier 7.x calls are still available,
but Oracle strongly recommends that existing applications use the new calls to improve performance
and provide increased functionality.
To get more information , check it in the chapter named "Introduction and Upgrading" in
OCI document .
4. Introduce to OCI Makefile
It's time to make out the source file , and the first one is Makefile which is a trunk in a project .
But then it is the end of a first exploration .
Notice that the head files of OCI are put in two directories and the lib file is libclntsh.so.9.0
which is the same as Pro*C . This is a simple one , just copy the code in last article and
divide into the corresponding files as the list . Then use "make all" or "make clean" to deal with
the source file automaticly . You would see something like this .
[root@liwei oci]# make clean;
rm -f OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o
[root@liwei oci]# make all;
[OCIDB.o]
---------------------
g++ -g -o OCIDB.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIDB.cpp
[OCIException.o]
---------------------
g++ -g -o OCIException.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIException.cpp
[Exception.o]
---------------------
g++ -g -o Exception.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Exception.cpp
[OCIError.o]
---------------------
g++ -g -o OCIError.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIError.cpp
[Main.o]
---------------------
g++ -g -o Main.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Main.cpp
[link] ...
---------------------
g++ -g -o OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o -L/home/ora/ora9/oracle/lib -lclntsh
That's good . Take a rest for next step .
-------------------------------------------------------------------------------------------------------
Oracle鏁版嵁搴撳紑鍙?鍏?.OCI搴旂敤鍒濇帰
鑽夋湪鐡?/p>
2007.6.25
涓銆佸簭
鍦ㄤ笂涓嬈★紝鎴戞彁渚涗簡涓涓畬鏁寸殑OCI紺轟緥錛屽唴瀹瑰寘鎷暟鎹簱榪炴帴鍜孲QL鎿嶄綔鐨勫疄闄呬唬鐮併?br>褰撶劧涓涓皬渚嬪瓙涓嶅彲鑳藉寘鎷墍鏈夊唴瀹癸紝涓嶈繃鎴戣涓哄鍒濆鑰呮槸涓涓笉閿欑殑寮濮嬨?/p>
涓嶱ro*C涓鏍鳳紝闇瑕佺‘璁ゅ畨瑁匫CI緇勪歡錛屾煡鐪嬩笅闈㈢殑璺緞錛?br>
Windows : $ORACLE_HOME\oci
Linux/Unix : $ORACLE_HOME/rdbms/demo
榪欎簺鐩綍鍖呭惈涓浜涚敱ORACLE鎻愪緵鐨勪竴浜涚ず渚嬨傝櫧鐒舵湁浜涙潅涔憋紝涓嶈繃榪樻槸涓浜涘府鍔╃殑銆?br> 鎴戜滑榪欓噷浣跨敤鐨勪富瑕佸鉤鍙版槸Linux銆?Windows涓嬫庝箞璁劇疆鍛紵鍙互鍙傝銆奜racle鏁版嵁搴?br>寮鍙?涓).Windows涓嬮厤緗嬌鐢≒roC銆嬩竴鏂囷紝閮芥槸綾諱技鐨勩?/p>
浜屻佷竴浜涗綘闇瑕佺煡閬撶殑涓滆タ
OCI鏄粈涔?錛?br>
OCI鏄竴緇勫簳灞傜殑API(搴旂敤紼嬪簭鎺ュ彛)錛屼富瑕佸拰Oracle鏁版嵁搴撹繘琛屼氦浜掋備綘鍙互璋冪敤涓浜?br>鎿嶄綔濡?logon , execute, parse, fecth 絳夌瓑銆侽CI鏀寔澶ф暟鎹璦錛岄氬父浣跨敤C/C++銆備笌Oracle
Pro*C絳変笉鍚岋紝OCI涓嶉渶瑕侀緙栬瘧銆?/p>
鎴戣繖閲屼篃鎵劇潃涓浠藉叧浜庡湪Pro*C鍜孫CI涔嬮棿閫夋嫨鐨勫畼鏂硅鏄庛?br>
鎴戝簲璇ヤ嬌鐢∣CI榪樻槸Pro*C錛?br>
OCI姣擯ro*C鐨勪竴浜涗紭鍔匡細
OCI鐨勬ц兘鍗佸垎鍑鴻壊
浠g爜澶ч噺緙╁噺
瀵瑰唴緗嚱鏁扮洿鎺ヨ闂?br> 瀵筁ONG綾誨瀷鐨勫垎孌墊搷浣?鍙互澶勭悊LONG鐩稿叧鐨勪換浣曢敊璇?
Pro*C涓嶈兘涓虹粦瀹氬彉閲忓姩鎬佸垎閰嶅唴瀛?br> 涓嶈兘鎺у埗Pro*C鑷姩鐢熸垚鐨勪唬鐮?span class=Apple-converted-space>
鐪嬭繃涓婅妭錛屼綘浼氬彂鐜頒竴浜涘鎬殑鍗曡瘝錛宱exec , ologoff 鎴?oclose 銆傝繖浜涢兘鏄厛鍓嶇増鏈?br>鏃х殑OCI鏍囧噯銆?/p>
OCI 8.0 寮曞叆涓濂楀叏鏂扮殑紼嬪簭緇撴瀯錛屾槸7.3浠ュ墠娌℃湁鐨勩?.1鐗堟湰鍙堟墿灞曚簡涓浜涘嚱鏁般?br>鍦∣racle 9i涓櫧鐒舵敮鎸佽繖浜涙棫鐨勬爣鍑嗭紝涓嶈繃Oracle寮虹儓寤鴻浣跨敤鍏ㄦ柊鐨凮CI鏍囧噯搴撱?br> 鍙傝僌CI鏂囨。涓?浠嬬粛鍜屽崌綰у唴瀹?涓鑺傦紝鑾峰彇鏇村淇℃伅銆?br>
鍥涖丱CI Makefile 浠嬬粛
鐜板湪宸笉澶氳浠嬬粛婧愪唬鐮佷簡錛岄鍏堢殑鏄疢akefile鏂囦歡錛屽彲浠ヨ鎴愭槸鏁翠釜欏圭洰鐨勪腑蹇冿紝鍙?br>鐪嬩緥涓殑鏂囦歡鍐呭銆傛敞鎰忓ご鏂囦歡鐩綍鏈変袱涓紝搴撴枃浠跺拰Pro*C浣跨敤鐨勪竴鏍鳳紝榪樻槸 libclntsh.so.9.0 錛?br>鐩稿叧璺緞鑷凡璋冩暣銆?br> 榪欎釜Makefile姣旇緝綆鍗曪紝鎶婂墠闈㈡枃绔犵綏鍒楃殑鎵鏈変唬鐮佸鍒跺茍寤虹珛鐩稿簲鏂囦歡錛屼嬌鐢?make all"
"make clean" 鍛戒護錛屼綘搴旇鑳界湅鍒板涓嬬被浼肩殑鍐呭錛?nbsp;
[root@liwei oci]# make clean;
rm -f OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o
[root@liwei oci]# make all;
[OCIDB.o]
---------------------
g++ -g -o OCIDB.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIDB.cpp
[OCIException.o]
---------------------
g++ -g -o OCIException.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIException.cpp
[Exception.o]
---------------------
g++ -g -o Exception.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Exception.cpp
[OCIError.o]
---------------------
g++ -g -o OCIError.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIError.cpp
[Main.o]
---------------------
g++ -g -o Main.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Main.cpp
[link] ...
---------------------
g++ -g -o OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o -L/home/ora/ora9/oracle/lib -lclntsh
Makefile鐩稿叧鐭ヨ瘑鍙互鍘籊oogle涓涓嬶紝鏂囩珷浠庣幇鍦ㄥ紑濮嬶紝灝辮闄嗙畫浠嬬粛涓浜汷CI
瀹炶川鎬х殑鍐呭浜嗐?/p>
OCI(Oracle Call Inte***ce)鏄敱澶存枃浠跺拰搴撳嚱鏁扮瓑緇勬垚鐨勪竴濂桹racle鏁版嵁搴撳簲鐢ㄧ▼搴忕紪紼嬫帴鍙e伐鍏鳳紝OCI紼嬪簭瀹炶川涓婂氨鏄敤楂樼駭璇█鍐欑殑紼嬪簭錛屽叾鐗圭偣鏄唴閮ㄥ惈鏈夊OCI瀛愬嚱鏁板簱鐨勮皟鐢ㄣ?br>OCI紼嬪簭瀵瑰紑鍙戠幆澧冪殑瑕佹眰鐩稿杈冧綆錛屽彧瑕佹湁C璇█鐨凮CI寮鍙戝伐鍏峰寘鍜孋緙栬瘧鍣ㄥ氨鍙互錛岀▼搴忚璁$浉姣擯RO*C澶嶆潅浜嗙偣銆?/p>
1銆佸垱寤哄拰鍒濆鍖朞CI鐜
棣栧厛瑕佸湪婧愮▼搴忎腑鍖呭惈OCI澶存枃浠訛細#include <oci.h>
OCI鐜鍗砄CI鍑芥暟鐨勫伐浣滅幆澧冿紝鍦ㄨ皟鐢ㄥ叾浠栧嚱鏁頒箣鍓嶅繀欏誨厛璋冪敤OCIInitialize()鍜孫CIEnvInit()鍑芥暟鍒涘緩鍜屽垵濮嬪寲OCI鐜錛屽叾浠朞CI鍑芥暟瑕佸湪榪欎釜鐜涓墠鑳芥墽琛屻?br>鍏堝畾涔夊彉閲忥細
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涓鴻緭鍑哄弬鏁幫紝鏄竴涓寚鍚慜CI鐜鍙ユ焺鐨勬寚閽堬紝OCI_DEFAULT 鏄疧CI鐜鐨勫垵濮嬪寲妯″紡銆侽CIEnvInit()鍑芥暟涓殑size_t綾誨瀷鍙橀噺涓哄垎閰嶇粰鐢ㄦ埛鐨勫唴瀛樻暟閲忥紝dvoid **綾誨瀷鍙橀噺鎸囧悜鐢ㄦ埛鐨勫唴瀛樺尯鍩燂紝璇ュ尯鍩熺殑澶у皬絳変簬size_t綾誨瀷鍙橀噺銆?br>OCI鍑芥暟涓紝澶ч噺浣跨敤OCI瀹氫箟鐨勬暟鎹被鍨嬪拰瀹忥紝鍏跺畾涔夊彲鍙傝?ORACLE_HOME/rdbms/demo鐩綍涓嬬殑oci.h澶存枃浠躲?/p>
2銆佺敵璇峰彞鏌?br>鍙ユ焺鏄寚鍚慜CI搴撴墍鍒嗛厤鐨勫唴瀛樺尯鍩熺殑鎸囬拡錛岃鍐呭瓨鍖哄煙涓殑鏁版嵁鐢監CI搴撶淮鎶わ紝搴旂敤紼嬪簭鍙氳繃鍙ユ焺璁塊棶鍏朵腑鐨勬暟鎹備笅闈㈡槸搴旂敤紼嬪簭涓渶甯哥敤鐨勫嚑涓彞鏌勶細
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涓烘柊鐢寵鐨勫彞鏌勶紝m_envhp涓哄畠鐨勭埗鐜鍙ユ焺錛孫CI_HTYPE_ERROR涓哄彞鏌勭被鍨嬶紝琛ㄧず榪欐槸涓涓敊璇姤鍛婂彞鏌勶紝OCI_HTYPE_SERVER琛ㄧず鏈嶅姟鍣ㄥ彞鏌勶紝OCI_HTYPE_SVCCTX琛ㄧず鏈嶅姟鐜鍙ユ焺錛孫CI_HTYPE_STMT琛ㄧず璇彞鍙ユ焺銆?/p>
瀛樺偍鍦ㄥ彞鏌勪腑鐨勬暟鎹О涓哄彞鏌勫睘鎬э紝鎵鏈塐CI鍙ユ焺閮藉叿鏈夊睘鎬э紝鍙互璋冪敤OCIAttrGet()鍜孫CIAttrSet()鍑芥暟鏉ヨ鍙栥佽緗彞鏌勫睘鎬с?/p>
3銆佽繛鎺ユ湇鍔″櫒寤虹珛浼氳瘽
棣栧厛璋冪敤
OCIServerAttach(m_srvhp, m_errhp, (text *)"", strlen(""), OCI_DEFAULT);
鍑芥暟寤虹珛涓庢寚瀹氭湇鍔″櫒鐨勮繛鎺ワ紝text *綾誨瀷鍙橀噺涓虹┖錛岃〃紺鴻繛鎺ラ粯璁ゆ暟鎹簱鏈嶅姟錛孫CI_DEFAULT琛ㄧず搴旂敤紼嬪簭鐨勬搷浣滄ā寮忎負闃誨妯″紡錛屽湪榪欑鏂瑰紡涓嬶紝鍙湁褰揙CI璋冪敤瀹屾垚鍚庢墠灝嗘帶鍒舵潈榪斿洖緇欏鎴風搴旂敤紼嬪簭銆?/p>
鐒跺悗璋冪敤
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));
寤虹珛鏁版嵁搴撲細璇濄傛鍑芥暟闅愬惈鐢寵鏈嶅姟鍣ㄥ彞鏌勫拰鐢ㄦ埛浼氳瘽鍙ユ焺錛岀櫥褰曞悗錛屽彞鏌勬槸鍙鐨勶紝涓嶈兘鍐嶈緗彞鏌勫睘鎬с?/p>
4銆佹墽琛孲QL璇彞騫跺鐞嗘暟鎹?br>灝嗚鎵ц鐨凷QL璇彞copy鍒皊zSqlStr瀛楃涓蹭腑:
snprintf( szSqlStr, sizeof(szSqlStr), "select PASSWORD from USERS where USERNAME=’chen’ ");
鎵ц涓嬪垪璇彞錛?/p>
OCIStmtPrepare(m_stmthp, m_errhp, (text*)szSqlStr, (ub4) strlen(szSqlStr), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); //鍑嗗SQL璇彞
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); //鎵цSQL璇彞
5銆佺粨鏉熶細璇濇柇寮鏁版嵁搴撹繛鎺?br>OCILogoff( m_svchp, m_errhp );
6銆佹柇寮涓庢暟鎹簮鐨勮繛鎺ワ紝閲婃斁鍙ユ焺
OCIServerDetach( m_srvhp, m_errhp, OCI_DEFAULT ); //鏂紑涓庢暟鎹簮鐨勮繛鎺?br>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鐢熸垚鍙墽琛屾枃浠訛紙涓ょ鏂規硶錛?br>(1)鍚屾櫘閫氱殑C紼嬪簭錛?br> gcc -o exampled –I. –I$(ORACLE_HOME)/precomp/public example.c
(2)鍒╃敤Oracle鑷甫鐨凪ake鏂囦歡錛?br>棣栧厛灝?ORACLE_HOME/rdbms/demo/demo_rdbms.mk鏂囦歡copy鍒癘CI婧愮▼搴忔墍鍦ㄧ殑鐩綍錛屽皢婧愭枃浠剁紪璇戜負鐩爣鏂囦歡錛?br>#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錛宔xampled灝變負鐢熸垚鐨勫彲鎵ц鏂囦歡