﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-拂晓·明月·弯刀-文章分类-Oracle</title><link>http://www.cppblog.com/ietj/category/16343.html</link><description>观望，等待只能让出现的机会白白溜走</description><language>zh-cn</language><lastBuildDate>Tue, 22 Mar 2011 17:59:44 GMT</lastBuildDate><pubDate>Tue, 22 Mar 2011 17:59:44 GMT</pubDate><ttl>60</ttl><item><title>Oracle数据库开发(五).OCI开发示例</title><link>http://www.cppblog.com/ietj/articles/142536.html</link><dc:creator>一路风尘</dc:creator><author>一路风尘</author><pubDate>Tue, 22 Mar 2011 16:14:00 GMT</pubDate><guid>http://www.cppblog.com/ietj/articles/142536.html</guid><wfw:comment>http://www.cppblog.com/ietj/comments/142536.html</wfw:comment><comments>http://www.cppblog.com/ietj/articles/142536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ietj/comments/commentRss/142536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ietj/services/trackbacks/142536.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Oracle Database Development (5). A example for OCI DevelopmentVert MelonJun 24,20071.Preface&nbsp;If you skimmed through some articles wrote in series before,&nbsp; you would find that i am no...&nbsp;&nbsp;<a href='http://www.cppblog.com/ietj/articles/142536.html'>阅读全文</a><img src ="http://www.cppblog.com/ietj/aggbug/142536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ietj/" target="_blank">一路风尘</a> 2011-03-23 00:14 <a href="http://www.cppblog.com/ietj/articles/142536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库开发(七).OCI开发示例说明</title><link>http://www.cppblog.com/ietj/articles/142535.html</link><dc:creator>一路风尘</dc:creator><author>一路风尘</author><pubDate>Tue, 22 Mar 2011 16:13:00 GMT</pubDate><guid>http://www.cppblog.com/ietj/articles/142535.html</guid><wfw:comment>http://www.cppblog.com/ietj/comments/142535.html</wfw:comment><comments>http://www.cppblog.com/ietj/articles/142535.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ietj/comments/commentRss/142535.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ietj/services/trackbacks/142535.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: verdana, sans-serif; TEXT-ALIGN: left">
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Oracle Database Development (7).&nbsp; The thinking of the OCI example .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Vert Melon</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Jun 26,2007</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;The central content in this article is about the common operations with Oracle .&nbsp; Just&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>follow the instructions and enrich the relevant knowledge by the OCI official document .<br>I'd like to copy many sentences from OCI official document . It would save me many<span class=Apple-converted-space>&nbsp;</span><br>trouble and these sentences are more exactly .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">1. Connection</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Connection is surely a first step done with the database . OCI provides two mode of<span class=Apple-converted-space>&nbsp;</span><br>connection , which is Single User, Single Connection and Multiple Sessions or Connections.<br>&nbsp;The example also gave the both implement .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;a. Single User, Single Connection<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;-----------------------------------------------------------------------------<br>&nbsp;<br>&nbsp;An application maintains only a single user session for each database connection<span class=Apple-converted-space>&nbsp;</span><br>at any time .<br>&nbsp;<br>&nbsp;The corresponding functions in the example listed as follows :<br>&nbsp;OCIDB::Single_Conn()<br>&nbsp;OCIDB::Single_Disc()<br>&nbsp;<br>&nbsp;The calling order of routines :<br>&nbsp;<br>&nbsp;OCIEnvCreate<br>&nbsp;OCIHandleAlloc&nbsp; &lt;ERROR&gt;<br>&nbsp;OCILogon<br>&nbsp;<br>&nbsp;OCILogoff<br>&nbsp;OCIHandleFree&nbsp;&nbsp; &lt;ERROR&gt;<br>&nbsp;OCIHandleFree&nbsp;&nbsp; &lt;ENV&gt;<br>&nbsp;<br>&nbsp;An application of OCI must have one environment handle , which is created by OCIEnvCreate()<span class=Apple-converted-space>&nbsp;</span><br>here . The environment handle defines a context in which all OCI functions are invoked .<span class=Apple-converted-space>&nbsp;</span><br>It is the base of almost all of the other handles which would be seen in future.<br>&nbsp;OCIEnvCreate() creates and initializes an environment for OCI functions to work under .<br>&nbsp;This call should be invoked before any other OCI call and should be used instead of<br>the OCIInitialize() and OCIEnvInit() calls. OCIInitialize() and OCIEnvInit() calls will be<span class=Apple-converted-space>&nbsp;</span><br>supported for backward compatibility. But if you are writing a DLL or a shared library<span class=Apple-converted-space>&nbsp;</span><br>using OCI library then this call should definitely be used instead of OCIInitialize() and<span class=Apple-converted-space>&nbsp;</span><br>OCIEnvInit() call . OCIInitialize() and OCIEnvInit() call is used in OCIDB::Multiple_Conn() ,<span class=Apple-converted-space>&nbsp;</span><br>we'll cover it soon.<br>&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;Almost all OCI calls include in their parameter list one or more handles. A handle is an<span class=Apple-converted-space>&nbsp;</span><br>opaque pointer to a storage area allocated by the OCI library. You use a handle to store<span class=Apple-converted-space>&nbsp;</span><br>context or connection information, (for example, an environment or service context handle),<span class=Apple-converted-space>&nbsp;</span><br>or it may store information about OCI functions or data (for example, an error or describe<span class=Apple-converted-space>&nbsp;</span><br>handle). Handles can make programming easier, because the library, rather than the application,<span class=Apple-converted-space>&nbsp;</span><br>maintains this data.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Either OCIEnvCreate() or ( OCIInitialize() and OCIEnvInit() ) allocates a environment<span class=Apple-converted-space>&nbsp;</span><br>handle . I defined a private member variable named m_pOCIEnv to store it . You can find<br>&nbsp;the both routines return a address as environment handle .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;There is also a very important handle , which appears in mostly OCI calls . That is the<span class=Apple-converted-space>&nbsp;</span><br>error handle .The error handle maintains information about errors that occur during an OCI<span class=Apple-converted-space>&nbsp;</span><br>operation. If an error occurs in a call, the error handle can be passed to OCIErrorGet() to<span class=Apple-converted-space>&nbsp;</span><br>obtain additional information about the error that occurred.<br>&nbsp;Go and look at OCIException::CheckError() which shows a integral error management .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;After the preparation of Environment and Error , we will come to the actual code about<span class=Apple-converted-space>&nbsp;</span><br>the connection . OCILogon() and OCILogoff() is quite easy to us . Notice that&nbsp; a service<span class=Apple-converted-space>&nbsp;</span><br>context handle will be created during the time processing OCILogon().<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;A service context handle defines attributes that determine the operational context for<span class=Apple-converted-space>&nbsp;</span><br>OCI calls to a server. The service context contains three handles as its attributes, that<span class=Apple-converted-space>&nbsp;</span><br>represent a server connection, a user session, and a transaction.&nbsp; OCILogon() call also<span class=Apple-converted-space>&nbsp;</span><br>implicitly allocates server and user session handles associated with the session.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Is is a very good custom that release the resource allocated at first in an order when<span class=Apple-converted-space>&nbsp;</span><br>the program comes the end . OCIDB::Single_Disc() does it explicitly .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em"><br>&nbsp;b. Multiple Sessions or Connections<br>&nbsp;-----------------------------------------------------------------------------<br>&nbsp;<br>&nbsp;If an application needs to maintain multiple user sessions on a database connection,<span class=Apple-converted-space>&nbsp;</span><br>the application requires a different set of calls to set up the sessions and connections.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;The corresponding functions in the example listed as follows :<br>&nbsp;OCIDB::Multiple_Conn()<br>&nbsp;OCIDB::Multiple_Disc()<br>&nbsp;<br>&nbsp;The calling order of routines :<br>&nbsp;<br>&nbsp;OCIInitialize<br>&nbsp;OCIEnvInit<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Error&gt;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Server Context &gt;<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Server&gt;<br>&nbsp;OCIAttrSet&nbsp; &lt;Set Server Into ServerContext&gt;<br>&nbsp;OCIServerAttach &lt;AttachServer&gt;<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Session&gt;<br>&nbsp;OCIAttrSet&nbsp; &lt;Set Session Into ServerContext&gt;<br>&nbsp;OCISessionBegin<br>&nbsp;<br>&nbsp;...<br>&nbsp;<br>&nbsp;Compare with OCILogon() it becomes more complex . Each handle is allocated by<span class=Apple-converted-space>&nbsp;</span><br>hand here .<br>&nbsp;There is someting new . All OCI handles have attributes associated with them. These<span class=Apple-converted-space>&nbsp;</span><br>attributes represent data stored in that handle. You can read handle attributes using the<span class=Apple-converted-space>&nbsp;</span><br>attribute get call, OCIAttrGet(), and you can change them with the attribute set call,&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>OCIAttrSet(). OCIServerAttach() creates an access path to the data server for OCI<span class=Apple-converted-space>&nbsp;</span><br>operations. OCISessionBegin() establishes a session for a user against a particular server.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;This call is required for the user to be able to execute any operation on the server.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;Notice that the calling order of OCIAttrSet() or OCIServerAttach() is random . As the<br>same , either call OCIAttrSet() before OCISessionBegin() or call OCISessionBegin()&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>before OCIAttrSet() is OK .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;You can change the content of the file Main.cpp to implement the different operation .<span class=Apple-converted-space>&nbsp;</span><br>Some code for test is listed below :</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Single_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Single_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">2.&nbsp;Execute non-query SQL</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Non-query SQL means that SQL doesn't return any data , such as create , insert , delete<br>and so on . These SQL statements also could be comprehanded as DDL . OCI also support<span class=Apple-converted-space>&nbsp;</span><br>the bind for extern values and we will discuss it in next section.&nbsp; Please search the relevant<span class=Apple-converted-space>&nbsp;</span><br>code in the example.&nbsp; The function OCIDB::ExecuteSql() covers it .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;At first you should allocate a statement handle in the envionment handle. A statement<span class=Apple-converted-space>&nbsp;</span><br>handle is the context that identifies a SQL or PL/SQL statement and its associated attributes.<br>Every SQL statement must be prepared for execution by OCIStmtPrepare() then. This is a<span class=Apple-converted-space>&nbsp;</span><br>completely local call, requiring no round trip to the server. No association is made at this<span class=Apple-converted-space>&nbsp;</span><br>point between the statement and a particular server.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;After finished the steps above , call OCIStmtExecute() to execute the statement. For DDL<span class=Apple-converted-space>&nbsp;</span><br>statements, no further steps are necessary.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;You may use these code statements in Main.cpp as the following :<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.ExecuteSql("update liwei_test&nbsp; set id =123 where note='test' ");<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;<br>3. Bind variable<br>&nbsp;<br>&nbsp;Most DML statements, and some queries (such as those with a WHERE clause), require a<span class=Apple-converted-space>&nbsp;</span><br>program to pass data to Oracle as part of a SQL or PL/SQL statement. Such data can be constant<span class=Apple-converted-space>&nbsp;</span><br>or literal data, known when your program is compiled.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;insert into liwei_test (id,name,note)values(1,'aABD','cadsf')</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;This statement is a simple one to insert some data known. When you prepare a SQL statement<span class=Apple-converted-space>&nbsp;</span><br>or PL/SQL block that contains input data to be supplied at runtime, placeholders in the SQL statement<span class=Apple-converted-space>&nbsp;</span><br>or PL/SQL block mark where data must be supplied. For example, the following SQL statement<span class=Apple-converted-space>&nbsp;</span><br>contains three placeholders, indicated by the leading colons (for example, :id), that show where<span class=Apple-converted-space>&nbsp;</span><br>input data must be supplied by the program.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;insert into liwei_test (id,name,note)values(:id,:name,:note)<br>&nbsp;<br>&nbsp;In this example I also made two different way using the bind .&nbsp; Look at this content of Main.cpp :</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;A. One-off bind with a predefine structure</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.BindAddVar(":id", 19809);<br>&nbsp;&nbsp; db.BindAddVar(":name", "liwei");<br>&nbsp;&nbsp; db.BindAddVar(":note", "test");<br>&nbsp;&nbsp; db.BindSql("insert into liwei_test (id,name,note)values(:id,:name,:note) ");<br>&nbsp;&nbsp; db.BindAddVar(":id", 169);<br>&nbsp;&nbsp; db.BindAddVar(":name", "sstem ch");<br>&nbsp;&nbsp; db.BindSql("insert into liwei_test (id,name)values(:id,:name) ");<br>&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;<br>&nbsp;<br>&nbsp;OCIDB::BindAddVar() add the user parameters into the share variable which name<span class=Apple-converted-space>&nbsp;</span><br>is m_BindVars . It has several overrided patterns .<br>&nbsp;OCIDB::BindSql() execute the SQL statement binding the structural variable . All of<span class=Apple-converted-space>&nbsp;</span><br>the OCI operation needed is called in an order .<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;<br>&nbsp;Notice :&nbsp; OCIDB::BindAddVar() allocates memory automaticly as the bind variable need .<br>&nbsp;<br>&nbsp;<br>&nbsp;B.&nbsp; Bind the variable step by step consistent with the defined order of OCI</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.UserPrepare("insert into liwei_test (id,name,note)values(:id,:name,:note)");<br>&nbsp;&nbsp; db.UserBind(":id",10701);<br>&nbsp;&nbsp; db.UserBind(":name", "liweitest");<br>&nbsp;&nbsp; db.UserBind(":note", "asdfasdf");<br>&nbsp;&nbsp; db.UserExecute();<br>&nbsp;&nbsp; db.UserCommit();<br>&nbsp;&nbsp; db.UserFree();<br>&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;&nbsp;<br>&nbsp;<br>&nbsp;The process had been divided into several steps here . In this case you can extend some<span class=Apple-converted-space>&nbsp;</span><br>further functions more easily .&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Notice :&nbsp; The class function starts with "User" is a series which performs a common template .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;<br>&nbsp;Both the two methods above follow this calling order :<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;stmt&gt;<br>&nbsp;OCIStmtPrepare<br>&nbsp;OCIBindByName/OCIBindByPos<br>&nbsp;OCIStmtExecute<br>&nbsp;OCITransCommit/OCITransRollback<br>&nbsp;OCIHandleFree&nbsp; &lt;stmt&gt;<br>&nbsp;<br>&nbsp;<br>4. Get the Recordset from a SQL Select statement</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;In this section i'd like to introduce a simple query example about the select statement which<br>&nbsp;select-list cols is known before execution.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Query statements return data from the database to your application.&nbsp; When processing a query,<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;you must define an output variable or an array of output variables for each item in the select-list<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;from which you want to retrieve data.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.UserSelect("select id,name,note,value from liwei_test where note='test'");<br>&nbsp;&nbsp; while(db.UserFetch()==0) {<br>&nbsp;&nbsp;&nbsp; printf("id:%f\n", db.UserGetFloat("id"));<br>&nbsp;&nbsp;&nbsp; printf("name:%s\n", db.UserGetString("name"));<br>&nbsp;&nbsp;&nbsp; printf("note:%s\n", db.UserGetString("note"));<br>&nbsp;&nbsp;&nbsp; printf("value:%f\n\n", db.UserGetFloat("value"));<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; db.UserSelectFree();<br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;&nbsp;<br>&nbsp;<br>&nbsp;As you see ,&nbsp; a simple one is gave now , which still seems a bit complex . Firstly i defined<span class=Apple-converted-space>&nbsp;</span><br>a structure "TSelectVar"&nbsp; to store select-list . "TSelectVar" had a union to store values in<span class=Apple-converted-space>&nbsp;</span><br>different type . Then i encapsuled the select operation into the four parts .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;UserSelect<br>&nbsp;UserFetch<br>&nbsp;UserGet<br>&nbsp;UserSelectFree<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;<br>&nbsp;So let's have a look at the first part --&nbsp; OCIDB::UserSelect() .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;OCIHandleAlloc() , OCIStmtPrepare(), OCIStmtExecute() and then the OCIAttrGet() !<br>&nbsp;I want to know the column count of the select-list , so used OCIAttrGet() there . For each<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;column , i called OCIParamGet() to get a OCI parameter and then used OCIAttrGet() to<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;fetch lots of useful imformation such as name, size, presision and so on .<br>&nbsp;<br>&nbsp;After the get of attribute , you should define the content of the select-list using OCIDefineByPos()<br>&nbsp;or OCIDefineByName() then.<br>&nbsp;<br>&nbsp;The purpose of these Get() and Define() calls is to describe the select-list for the following<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;action which is get .&nbsp; OCIDB::UserFetch() is easily comprehanded , for only one call OCIStmtFetch<br>&nbsp;in it .<br>&nbsp;<br>&nbsp;Pay attention to the member function like OCIDB::UserGet , these functions is interface<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;to exterior user . It is overrided also .<br>&nbsp;<br>&nbsp;&nbsp; int UserGetInt(int index);<br>&nbsp;&nbsp; int UserGetInt(char * name);<br>&nbsp;&nbsp; char * UserGetString(int index);<br>&nbsp;&nbsp; char * UserGetString(char * name);&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp; float UserGetFloat(int index);<br>&nbsp;&nbsp; float UserGetFloat(char * name);<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;Peruse the code patiently and you will gain much knowledge .<br>&nbsp;<br>5.The Last</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;This example is just for a demonstration or a accidence . You mush not stop here only .<span class=Apple-converted-space>&nbsp;</span><br>Take this way for more info by practice and online help. Obviousely there are many points<span class=Apple-converted-space>&nbsp;</span><br>which are not very standard in the article , for a exam i didn't use CONST while passing a<span class=Apple-converted-space>&nbsp;</span><br>value . This is a important aspect to improve .<br>&nbsp;&nbsp; For you may not acclimatize youself&nbsp; to the variety of the OCI type , take it easy , try to<br>get together with the OCI Function Reference and force a type conversion .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">-------------------------------------------------------------------------------------------------------</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Oracle数据库开发(七).OCI示例开发说明</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">草木瓜</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">2007-6-26</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;这篇文章的主要内容是介绍的常见的OCI数据操作。可以顺着文章思路结合OCI<br>相关Oracle文档去理解。这里从原文档中复制了不少原句，这个省了很多麻烦而且<br>这些表达更为准确。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">一、数据库连接</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;数据库连接是操作数据库的第一步。OCI提供了两种模式的连接，即单用户<br>单连接和多用户多连接。我这里的OCI示例也分别提供了两种实现方式。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;a.单用户，单连接<br>&nbsp;-----------------------------------------------------------------------------<br>&nbsp;<br>&nbsp;应用程序对于某一数据库连接仅支持单用户进程。<br>&nbsp;<br>&nbsp;例子中对应的函数过程：<br>&nbsp;OCIDB::Single_Conn()<br>&nbsp;OCIDB::Single_Disc()<br>&nbsp;<br>&nbsp;OCI内部过程的调用顺序如下：<br>&nbsp;<br>&nbsp;OCIEnvCreate<br>&nbsp;OCIHandleAlloc&nbsp; &lt;ERROR&gt;<br>&nbsp;OCILogon<br>&nbsp;<br>&nbsp;OCILogoff<br>&nbsp;OCIHandleFree&nbsp;&nbsp; &lt;ERROR&gt;<br>&nbsp;OCIHandleFree&nbsp;&nbsp; &lt;ENV&gt;<br>&nbsp;<br>&nbsp;OCI应用程序必须有一个环境句柄，在这里由 OCIEnvCreate()创建。环境句柄相当<br>于定义一个容器，包含了以后的所有OCI句柄，这是OCI调用的基础。<br>&nbsp;OCIEnvCreate()创建并初始化了一个OCI函数的工作环境，必须先于其他OCI函数<br>之前调用。一般来说，从兼容性方面考虑，最好使用OCIInitialize() 和 OCIEnvInit()替代<br>OCIEnvCreate()。不过如果你在写dll或者共享库之类的东西，最好还是用OCIEnvCreate()。<br>OCIDB::Multiple_Conn()中就使用了OCIInitialize()和OCIEnvInit() ，我们一会会提到。<br>&nbsp;<br>&nbsp;绝大多数的OCI调用都使用了一个或多个句柄。句柄指向由OCI库自动分配的内存<br>空间。可以存储连接环境信息(如，数据库连接环境或服务环境句柄) ，OCI函数执行<br>过程中相关信息(如，错误句柄或者描述句柄)。OCI句柄让开发工作变得简单起来，<br>这些相关信息是由OCI库所管理，而不是用户的应用程序。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;不管是OCIEnvCreate()还是(OCIInitialize()和OCIEnvInit())都分配了一个数据库环境句<br>柄。我这里定义了私有成员变量m_pOCIEnv用来存储环境句柄。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;OCI中还有一个很重要的句柄，经常出现在OCI调用过程中。这就是错误句柄。错误<br>句柄管理在OCI数据操作中出现的各类错误，如果在调用中出错，可以把错误句柄<br>传递给OCIErrorGet()来获取更多的错误信息。<br>&nbsp;OCIException::CheckError() 是一个完整的错误处理示例。<br>&nbsp;<br>&nbsp;准备好环境句柄和错误句柄后，该到数据库连接的实际代码了。这里的OCILogon()<span class=Apple-converted-space>&nbsp;</span><br>和 OCILogoff() 理解起来并不难。要注意OCILogon()执行过程中返回了一个服务环境<br>句柄。<br>&nbsp;服务环境句柄定义一些重要属性，直接决定了连接数据库的方式方法。服务环境<br>句柄包含三个属性，其实就是另外独立的三个句柄，即服务连接，用户会话和事务。<br>&nbsp;OCILogon()执行过程中其实也声明了服务连接和用户会话的相关句柄，只不过是隐<br>式声明。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;在程序结束时手工释放资源是很好的习惯，可参见OCIDB::Single_Disc()。<br>&nbsp;<br>&nbsp;b.多用户，多连接<br>&nbsp;-----------------------------------------------------------------------------</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;如果应用程序对单一数据库连接需要维护多个用户会话，就需要使用另一种方式了。<br>&nbsp;<br>&nbsp;例子中对应的函数过程：<br>&nbsp;OCIDB::Multiple_Conn()<br>&nbsp;OCIDB::Multiple_Disc()<br>&nbsp;<br>&nbsp;OCI内部过程的调用顺序如下：<br>&nbsp;<br>&nbsp;OCIInitialize<br>&nbsp;OCIEnvInit<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Error&gt;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Server Context &gt;<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Server&gt;<br>&nbsp;OCIAttrSet&nbsp; &lt;Set Server Into ServerContext&gt;<br>&nbsp;OCIServerAttach &lt;AttachServer&gt;<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;Session&gt;<br>&nbsp;OCIAttrSet&nbsp; &lt;Set Session Into ServerContext&gt;<br>&nbsp;OCISessionBegin<br>&nbsp;<br>&nbsp;...<br>&nbsp;<br>&nbsp;与OCILogon()相比，变的有些复杂，每个句柄在这里都是手工去创建。需要提出<br>的是，所有的OCI句柄都有其相关属性，这些属性存储了一些有用的数据。可以使<br>用OCIAttrGet()获取对应信息，也可以通过OCIAttrSet()进行修改。OCIServerAttach()<span class=Apple-converted-space>&nbsp;</span><br>创建了一个OCI操作的数据服务访问路径，OCISessionBegin() 确立用户会话连接。<br>这里完成后，才可以进行实际的数据操作。<br>&nbsp;注意这里的OCIAttrSet()和OCIServerAttach()的调用顺序不是固定的，类似的 OCISessionBegin()<span class=Apple-converted-space>&nbsp;</span><br>和 OCIAttrSet() 先后顺序也是可以互换的。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;你可以自行更改Main.cpp内容以完成不同的数据操作。<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Single_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Single_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">二、执行无返回值的SQL语句</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;这类语句一般包括create , insert和delete等等，无返回值语句一般也可以理解为DDL<br>语句。OCI也支持对SQL语句进行变量绑定，下节会专门讨论。<br>&nbsp;例子中相关的函数是OCIDB::ExecuteSql() 。<br>&nbsp;<br>&nbsp;首先你需要在环境句柄中声明一个语句句柄。语句句柄包含了SQL或者PL/SQL<br>语句及其相关属性，每个SQL语句在执行前必须要使用OCIStmtPrepare()进行预处理。<br>这个是本地化调用，不会向服务器端发送请求。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;完成上面步骤后，就可以调用OCIStmtExecute() 执行SQL语句了。<br>&nbsp;<br>&nbsp;代码语句如下：<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; &nbsp;OCIDB db;<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp;&nbsp;&nbsp; db.ExecuteSql("update liwei_test&nbsp; set id =123 where note='test' ");<br>&nbsp;&nbsp;&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}<br>&nbsp;<br>三、变量绑定</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;大多数DML语句或者一些查询(带where条件的)需要向SQL传递一些数据，下面的例子<br>是在程序编译时就已经知道要传递的数值。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;insert into liwei_test (id,name,note)values(1,'aABD','cadsf')<br>&nbsp;<br>&nbsp;这是个简单的例子，当预处理一个SQL语句或者PL/SQL块，其中有些数值是需要在运<br>行中才能确定的。这时就需要在运行动态去绑定变量了，我们在SQL语句或者PL/SQL块<br>中使用:id之类的符号，表示可以做为变量绑定。如：</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;insert into liwei_test (id,name,note)values(:id,:name,:note)<br>&nbsp;<br>&nbsp;这个例子中，我使用了两种途径来绑定变量。<br>&nbsp;<br>&nbsp;A.通过预定义的结构体一次性绑定<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.BindAddVar(":id", 19809);<br>&nbsp;&nbsp; db.BindAddVar(":name", "liwei");<br>&nbsp;&nbsp; db.BindAddVar(":note", "test");<br>&nbsp;&nbsp; db.BindSql("insert into liwei_test (id,name,note)values(:id,:name,:note) ");<br>&nbsp;&nbsp; db.BindAddVar(":id", 169);<br>&nbsp;&nbsp; db.BindAddVar(":name", "sstem ch");<br>&nbsp;&nbsp; db.BindSql("insert into liwei_test (id,name)values(:id,:name) ");<br>&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}<br>&nbsp;<br>&nbsp;OCIDB::BindAddVar() 将相关的用户变量参数添加到m_BindVars变量中，这个函数<br>有不同的重载形式。<br>&nbsp;OCIDB::BindSql() 绑定结构体定义的变量，并执行SQL语句。<br>&nbsp;<br>&nbsp;注意：OCIDB::BindAddVar() 根据绑定的变量值自动分配内存<br>&nbsp;<br>&nbsp;B. 根据OCI内部顺序一步一步绑定<br>&nbsp;<br>&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.UserPrepare("insert into liwei_test (id,name,note)values(:id,:name,:note)");<br>&nbsp;&nbsp; db.UserBind(":id",10701);<br>&nbsp;&nbsp; db.UserBind(":name", "liweitest");<br>&nbsp;&nbsp; db.UserBind(":note", "asdfasdf");<br>&nbsp;&nbsp; db.UserExecute();<br>&nbsp;&nbsp; db.UserCommit();<br>&nbsp;&nbsp; db.UserFree();<br>&nbsp;&nbsp; db.Multiple_Disc();<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;&nbsp;<br>&nbsp;<br>&nbsp;这里把整个过程划分成多步，可以方便以后扩展功能。<br>&nbsp;<br>&nbsp;注意：User打头的这些系列函数，其实是比较常用的一套模板。<br>&nbsp;<br>&nbsp;这两种方式调用OCI内部函数的顺序都是一样的：<br>&nbsp;<br>&nbsp;OCIHandleAlloc&nbsp; &lt;stmt&gt;<br>&nbsp;OCIStmtPrepare<br>&nbsp;OCIBindByName/OCIBindByPos<br>&nbsp;OCIStmtExecute<br>&nbsp;OCITransCommit/OCITransRollback<br>&nbsp;OCIHandleFree&nbsp; &lt;stmt&gt;s<br>&nbsp;<br>四、从Select语句获取记录集</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;这节主要介绍一个简单的查询例子，例子中的查询列在执行前已经知道。<br>&nbsp;查询语句返回数据库中所需数据，执行查询时必须要定义外部的输出变量或者变<br>量数组来存储你所需要检索的数据。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;#include "OCIDB.h"<br>&nbsp;int main() {<br>&nbsp;<br>&nbsp;&nbsp; OCIDB db;<br>&nbsp;&nbsp; db.Multiple_Conn();<br>&nbsp;&nbsp; db.UserSelect("select id,name,note,value from liwei_test where note='test'");<br>&nbsp;&nbsp; while(db.UserFetch()==0) {<br>&nbsp;&nbsp;&nbsp; printf("id:%f\n", db.UserGetFloat("id"));<br>&nbsp;&nbsp;&nbsp; printf("name:%s\n", db.UserGetString("name"));<br>&nbsp;&nbsp;&nbsp; printf("note:%s\n", db.UserGetString("note"));<br>&nbsp;&nbsp;&nbsp; printf("value:%f\n\n", db.UserGetFloat("value"));<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; db.UserSelectFree();<br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;}&nbsp;&nbsp;<br>&nbsp;<br>&nbsp;上面就是一个小例子。首先我先定义了一个结构体TSelectVar(与绑定变量的结构体<br>类似)准备存储返回的结果集。TSelectVar 中使用了Union存储不同类型的数值。然后<br>我把整个OCI Select过程封装成如下四部分：<br>&nbsp;<br>&nbsp;UserSelect<br>&nbsp;UserFetch<br>&nbsp;UserGet<br>&nbsp;UserSelectFree<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;<br>&nbsp;我们先看第一部分 OCIDB::UserSelect() 。<br>&nbsp;OCIHandleAlloc() , OCIStmtPrepare(), OCIStmtExecute() 然后是OCIAttrGet() 。<br>&nbsp;OCIAttrGet()主要是为了获取返回结果集的列数。对于每一列，使用了OCIParamGet()<br>&nbsp;先获取整列的OCIParm，然后再使用OCIAttrGet()依次获取象列名，列大小，精度等<br>&nbsp;有用的信息。<br>&nbsp;<br>&nbsp;获取这些属性后，就需要调用OCIDefineByPos()或OCIDefineByName为结果集定义<br>&nbsp;内容了。<br>&nbsp;<br>&nbsp;其实这些Get()和Define()就是为了描述Select执行后返回的结果集，方便我们获取其中<br>&nbsp;数据。OCIDB::UserFetch() 里面只有个OCIStmtFetch()，比较好理解，说白了就是控制<br>&nbsp;游标。<br>&nbsp;<br>&nbsp;注意象OCIDB::UserGet的这些个成员函数，是对外的数据接口，以下是不同的重载形<br>&nbsp;式：<br>&nbsp;<br>&nbsp;&nbsp; int UserGetInt(int index);<br>&nbsp;&nbsp; int UserGetInt(char * name);<br>&nbsp;&nbsp; char * UserGetString(int index);<br>&nbsp;&nbsp; char * UserGetString(char * name);&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp; float UserGetFloat(int index);<br>&nbsp;&nbsp; float UserGetFloat(char * name);<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;这里没有什么好说的，读读代码就会清楚。<br>&nbsp;<br>五、写在最后</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;这个例仅做演示。不过不必仅停留于此，如要提高，结合在线文档多练即可。<br>这个例子的代码在某些方面显然不够规范，如未在传值中使用const，这也是以后<br>要提高的方面。<br>&nbsp;另外，刚接触OCI时，可能会对内部的一堆类型不太适应，这里多看看函数的参考，<br>尽量做一些强制性的转换。&nbsp;</p>
</span></span>
<img src ="http://www.cppblog.com/ietj/aggbug/142535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ietj/" target="_blank">一路风尘</a> 2011-03-23 00:13 <a href="http://www.cppblog.com/ietj/articles/142535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库开发(六).OCI应用初探</title><link>http://www.cppblog.com/ietj/articles/142534.html</link><dc:creator>一路风尘</dc:creator><author>一路风尘</author><pubDate>Tue, 22 Mar 2011 16:11:00 GMT</pubDate><guid>http://www.cppblog.com/ietj/articles/142534.html</guid><wfw:comment>http://www.cppblog.com/ietj/comments/142534.html</wfw:comment><comments>http://www.cppblog.com/ietj/articles/142534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ietj/comments/commentRss/142534.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ietj/services/trackbacks/142534.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: verdana, sans-serif; TEXT-ALIGN: left">
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Oracle Database Development (6). A first exploration of OCI</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Vert Melon</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Jun 25,2007</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">1.Preface</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Last time , i provided a full example of OCI , which contains the actual code of connection<span class=Apple-converted-space>&nbsp;</span><br>and SQL . Certainly it could not cover all of the knowledge , but i think it is a good beginning<span class=Apple-converted-space>&nbsp;</span><br>for the fresher .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;As the same as Pro*C you might confirm that you have installed it correctly .&nbsp; Look at this<span class=Apple-converted-space>&nbsp;</span><br>paths as follows :<br>&nbsp;<br>&nbsp;Windows&nbsp;&nbsp; :&nbsp;&nbsp; $ORACLE_HOME\oci<br>&nbsp;Linux/Unix&nbsp; :&nbsp;&nbsp; $ORACLE_HOME/rdbms/demo<br>&nbsp;<br>&nbsp;There are many examples offered by ORACLE . Though it seems like a clutter , you also<span class=Apple-converted-space>&nbsp;</span><br>can get some useful imformation .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;The main platform we use here is Linux .&nbsp; And the Windows ?&nbsp; How can i config it in Windows ?<span class=Apple-converted-space>&nbsp;</span><br>It would be a comfy thing if you have read the chapters recorded in&nbsp; &lt;Oracle Database Development (1). Config OCI In Windows&gt; .<br>It is easily comprehend by analogy .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em"><br>2.Something you should know</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;What is the Oracle Call Interface?</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;The Oracle Call Interface (OCI) is a set of low-level APIs (Application Programming Interface Calls)<span class=Apple-converted-space>&nbsp;</span><br>used to interact with Oracle databases. It allows one to use operations like logon, execute,<span class=Apple-converted-space>&nbsp;</span><br>parse, fetch, etc. OCI programs are normally written in C or C++, although they can be written<br>in almost any programing language. Unlike with the Oracle Precompilers (like Pro*C and Pro*COBOL),<span class=Apple-converted-space>&nbsp;</span><br>OCI programs are not precompiled.</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Also I have found a official explaination about the choice between Pro*C and OCI .<br>&nbsp;<br>&nbsp;Should one use OCI or the Oracle Precompilers?<br>&nbsp;<br>&nbsp;OCI is superior to Pro*C in the following ways:<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Performance is much better with OCI<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Reduced code size<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Direct access to built-in functions (No intermediate files or substitutions).<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Piecewise Operation on LONG fields (All LONG field problems are solved)<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;In Pro*C one cannot dynamically allocate memory to be used as bind variables<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;You cannot control the Pro*C precompiler to provide better and more compilable C-code.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;Common problems with OCI:<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;OCI code is difficult to write and to maintain<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Very few people can write, let alone maintain OCI code<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;...<br>&nbsp;&nbsp;<br>&nbsp;An OCI application program must do the following:<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Connect to one or more databases: call the OCILogon (olog, olon or orlon) routines<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Open the cursors needed by the program: use oexec, oexn, ofen or oftech calls.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Process the SQL statements that are needed to perform the application's tasks.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Close the cursors using the oclose routine.<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;Disconnect from the databases: use ologoff to close an open connection to oracle. &nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">3.Obsolescent OCI Routines</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;After get through the section "Something you should know" ,&nbsp; you may find some strange<span class=Apple-converted-space>&nbsp;</span><br>words : oexec , ologoff&nbsp; or oclose . There are old routines in preceding release .<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;Release 8.0 of the Oracle Call Interface introduced an entirely new set of functions which<span class=Apple-converted-space>&nbsp;</span><br>were not available in release 7.3. Release 8.1 added more new functions. Oracle9i OCI continues<span class=Apple-converted-space>&nbsp;</span><br>to support these new functions, and adds more new calls. The earlier 7.x calls are still available,<span class=Apple-converted-space>&nbsp;</span><br>but Oracle strongly recommends that existing applications use the new calls to improve performance<span class=Apple-converted-space>&nbsp;</span><br>and provide increased functionality.<br>&nbsp;To get more information ,&nbsp; check it in the chapter named "Introduction and Upgrading" in<span class=Apple-converted-space>&nbsp;</span><br>OCI document .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em"><br>4. Introduce to OCI Makefile</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;It's time to make out the source file , and the first one is Makefile which is a trunk in a project .<br>But then it is the end of&nbsp; a first exploration .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Notice that the head files of OCI are put in two directories and the lib file is libclntsh.so.9.0<span class=Apple-converted-space>&nbsp;</span><br>which is the same as Pro*C .&nbsp; This is a simple one ,&nbsp; just copy the code in last article and<span class=Apple-converted-space>&nbsp;</span><br>divide into the corresponding files as the list . Then use "make all" or "make clean" to deal with<span class=Apple-converted-space>&nbsp;</span><br>the source file automaticly . You would see something like this .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[root@liwei oci]# make clean;<br>rm -f OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o<br>[root@liwei oci]# make all;<br>[OCIDB.o]<br>---------------------<br>g++ -g -o OCIDB.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIDB.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[OCIException.o]<br>---------------------<br>g++ -g -o OCIException.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIException.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[Exception.o]<br>---------------------<br>g++ -g -o Exception.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Exception.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[OCIError.o]<br>---------------------<br>g++ -g -o OCIError.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIError.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[Main.o]<br>---------------------<br>g++ -g -o Main.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Main.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[link] ...<span class=Apple-converted-space>&nbsp;</span><br>---------------------<br>g++ -g -o OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o -L/home/ora/ora9/oracle/lib -lclntsh</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;That's good . Take a rest for next step .</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">-------------------------------------------------------------------------------------------------------</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">Oracle数据库开发(六).OCI应用初探</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">草木瓜</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">2007.6.25 &nbsp;<br>&nbsp;<br>一、序</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;在上一次，我提供了一个完整的OCI示例，内容包括数据库连接和SQL操作的实际代码。<br>当然一个小例子不可能包括所有内容，不过我认为对初学者是一个不错的开始。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;与Pro*C一样，需要确认安装OCI组件，查看下面的路径：<br>&nbsp;<br>&nbsp;Windows&nbsp;&nbsp; :&nbsp;&nbsp; $ORACLE_HOME\oci<br>&nbsp;Linux/Unix&nbsp; :&nbsp;&nbsp; $ORACLE_HOME/rdbms/demo<br>&nbsp;<br>&nbsp;这些目录包含一些由ORACLE提供的一些示例。虽然有些杂乱，不过还是一些帮助的。<br>&nbsp;我们这里使用的主要平台是Linux。 Windows下怎么设置呢？可以参见《Oracle数据库<br>开发(一).Windows下配置使用ProC》一文，都是类似的。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em"><br>二、一些你需要知道的东西</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;OCI是什么 ？<br>&nbsp;<br>&nbsp;OCI是一组底层的API(应用程序接口)，主要和Oracle数据库进行交互。你可以调用一些<br>操作如 logon , execute, parse, fecth 等等。OCI支持大数据语言，通常使用C/C++。与Oracle<br>Pro*C等不同，OCI不需要预编译。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;我这里也找着一份关于在Pro*C和OCI之间选择的官方说明。<br>&nbsp;<br>&nbsp;我应该使用OCI还是Pro*C？<br>&nbsp;<br>&nbsp;OCI比Pro*C的一些优势：<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;OCI的性能十分出色<br>&nbsp;&nbsp;代码大量缩减<br>&nbsp;&nbsp;对内置函数直接访问<br>&nbsp;&nbsp;对LONG类型的分段操作(可以处理LONG相关的任何错误)<br>&nbsp;&nbsp;Pro*C不能为绑定变量动态分配内存<br>&nbsp;&nbsp;不能控制Pro*C自动生成的代码<span class=Apple-converted-space>&nbsp;</span><br>&nbsp;&nbsp;<br>&nbsp;OCI开发的一些常见问题：<br>&nbsp;<br>&nbsp;&nbsp;OCI代码不容易掌握<br>&nbsp;&nbsp;...<br>&nbsp;&nbsp;<br>&nbsp;OCI开发流程：<br>&nbsp;<br>&nbsp;&nbsp;连接多个数据库：使用OCILogon (olog, olon or orlon)<br>&nbsp;&nbsp;打开游标：oexec, oexn, ofen 或者 oftech<br>&nbsp;&nbsp;执行相应SQL语句<br>&nbsp;&nbsp;关于游标：oclose<br>&nbsp;&nbsp;断开连接：ologoff<br>&nbsp;&nbsp;<br>三、废弃的一些程序标准</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;看过上节，你会发现一些奇怪的单词，oexec , ologoff&nbsp; 或 oclose 。这些都是先前版本<br>旧的OCI标准。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;OCI 8.0 引入一套全新的程序结构，是7.3以前没有的。8.1版本又扩展了一些函数。<br>在Oracle 9i中虽然支持这些旧的标准，不过Oracle强烈建议使用全新的OCI标准库。<br>&nbsp;参考OCI文档中"介绍和升级内容"一节，获取更多信息。<br>&nbsp;<br>四、OCI Makefile 介绍</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;现在差不多该介绍源代码了，首先的是Makefile文件，可以说成是整个项目的中心，参<br>看例中的文件内容。注意头文件目录有两个，库文件和Pro*C使用的一样，还是 libclntsh.so.9.0 ，<br>相关路径自已调整。<br>&nbsp;这个Makefile比较简单，把前面文章罗列的所有代码复制并建立相应文件，使用"make all"<br>"make clean" 命令，你应该能看到如下类似的内容：&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[root@liwei oci]# make clean;<br>rm -f OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o<br>[root@liwei oci]# make all;<br>[OCIDB.o]<br>---------------------<br>g++ -g -o OCIDB.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIDB.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[OCIException.o]<br>---------------------<br>g++ -g -o OCIException.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIException.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[Exception.o]<br>---------------------<br>g++ -g -o Exception.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Exception.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[OCIError.o]<br>---------------------<br>g++ -g -o OCIError.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c OCIError.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[Main.o]<br>---------------------<br>g++ -g -o Main.o -I/home/ora/ora9/oracle/rdbms/demo -I/home/ora/ora9/oracle/rdbms/public -c Main.cpp</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">[link] ...<span class=Apple-converted-space>&nbsp;</span><br>---------------------<br>g++ -g -o OCIDB OCIDB.o OCIException.o Exception.o OCIError.o Main.o -L/home/ora/ora9/oracle/lib -lclntsh</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0.9em; MARGIN: 0px; PADDING-TOP: 0.9em">&nbsp;Makefile相关知识可以去Google一下，文章从现在开始，就要陆续介绍一些OCI<br>实质性的内容了。</p>
</span></span>
<img src ="http://www.cppblog.com/ietj/aggbug/142534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ietj/" target="_blank">一路风尘</a> 2011-03-23 00:11 <a href="http://www.cppblog.com/ietj/articles/142534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle入门 - OCI介绍</title><link>http://www.cppblog.com/ietj/articles/142533.html</link><dc:creator>一路风尘</dc:creator><author>一路风尘</author><pubDate>Tue, 22 Mar 2011 16:10:00 GMT</pubDate><guid>http://www.cppblog.com/ietj/articles/142533.html</guid><wfw:comment>http://www.cppblog.com/ietj/comments/142533.html</wfw:comment><comments>http://www.cppblog.com/ietj/articles/142533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ietj/comments/commentRss/142533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ietj/services/trackbacks/142533.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Tahoma; webkit-border-horizontal-spacing: 2px; webkit-border-vertical-spacing: 2px">
<p>OCI(Oracle Call Inte***ce)是由头文件和库函数等组成的一套Oracle数据库应用程序编程接口工具，OCI程序实质上就是用高级语言写的程序，其特点是内部含有对OCI子函数库的调用。<br>OCI程序对开发环境的要求相对较低，只要有C语言的OCI开发工具包和C编译器就可以，程序设计相比PRO*C复杂了点。</p>
<p>1、创建和初始化OCI环境<br>首先要在源程序中包含OCI头文件：#include &lt;oci.h&gt;<br>OCI环境即OCI函数的工作环境，在调用其他函数之前必须先调用OCIInitialize()和OCIEnvInit()函数创建和初始化OCI环境，其他OCI函数要在这个环境中才能执行。<br>先定义变量：<br>OCIEnv**&nbsp;&nbsp; m_envhp;<br>OCIError*&nbsp; m_errhp;<br>OCIServer* m_srvhp;<br>OCISvcCtx* m_svchp;<br>OCIStmt *&nbsp; m_stmthp;</p>
<p>OCIInitialize(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ub4) OCI_DEFAULT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid *)0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid * (*)(dvoid *, size_t))0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid * (*)(dvoid *, dvoid *, size_t))0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void (*)(dvoid *, dvoid *))0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>OCIEnvInit(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (OCIEnv **)&amp;m_envhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OCI_DEFAULT, (size_t)0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>其中m_envhp为输出参数，是一个指向OCI环境句柄的指针，OCI_DEFAULT 是OCI环境的初始化模式。OCIEnvInit()函数中的size_t类型变量为分配给用户的内存数量，dvoid **类型变量指向用户的内存区域，该区域的大小等于size_t类型变量。<br>OCI函数中，大量使用OCI定义的数据类型和宏，其定义可参考$ORACLE_HOME/rdbms/demo目录下的oci.h头文件。</p>
<p>2、申请句柄<br>句柄是指向OCI库所分配的内存区域的指针，该内存区域中的数据由OCI库维护，应用程序可通过句柄访问其中的数据。下面是应用程序中最常用的几个句柄：<br>OCIHandleAlloc(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid *)m_envhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)&amp;m_errhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OCI_HTYPE_ERROR,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (size_t)0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>OCIHandleAlloc(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid *)m_envhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)&amp;m_srvhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OCI_HTYPE_SERVER,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (size_t)0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>OCIHandleAlloc(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid *)m_envhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)&amp;m_svchp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OCI_HTYPE_SVCCTX,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (size_t) 0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>OCIHandleAlloc(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid *)m_envhp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)&amp;m_stmthp,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OCI_HTYPE_STMT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (size_t)0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dvoid **)0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>其中m_errhp为新申请的句柄，m_envhp为它的父环境句柄，OCI_HTYPE_ERROR为句柄类型，表示这是一个错误报告句柄，OCI_HTYPE_SERVER表示服务器句柄，OCI_HTYPE_SVCCTX表示服务环境句柄，OCI_HTYPE_STMT表示语句句柄。</p>
<p>存储在句柄中的数据称为句柄属性，所有OCI句柄都具有属性，可以调用OCIAttrGet()和OCIAttrSet()函数来读取、设置句柄属性。</p>
<p>3、连接服务器建立会话<br>首先调用<br>OCIServerAttach(m_srvhp, m_errhp, (text *)"", strlen(""), OCI_DEFAULT);<br>函数建立与指定服务器的连接，text *类型变量为空，表示连接默认数据库服务，OCI_DEFAULT表示应用程序的操作模式为阻塞模式，在这种方式下，只有当OCI调用完成后才将控制权返回给客户端应用程序。</p>
<p>然后调用<br>OCILogon(m_envhp,m_errhp, &amp;m_svchp, (text*)m_szUser,strlen(m_szUser), (text*)m_szPassword, strlen(m_szPassword), (text*)m_szDbName, strlen(m_szDbName));<br>建立数据库会话。此函数隐含申请服务器句柄和用户会话句柄，登录后，句柄是只读的，不能再设置句柄属性。</p>
<p>4、执行SQL语句并处理数据<br>将要执行的SQL语句copy到szSqlStr字符串中:<br>snprintf( szSqlStr, sizeof(szSqlStr), "select PASSWORD from USERS where USERNAME=&#8217;chen&#8217; ");<br>执行下列语句：</p>
<p>OCIStmtPrepare(m_stmthp, m_errhp, (text*)szSqlStr, (ub4) strlen(szSqlStr), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); //准备SQL语句</p>
<p>OCIDefine *defnp0 = (OCIDefine *) 0; //定义输出变量</p>
<p>OCIDefineByPos( m_stmthp, &amp;defnp0, m_errhp, 1, (dvoid *)szUSERNAME, 100, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); //绑定变量</p>
<p>OCIStmtExecute( m_svchp, m_stmthp, m_errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL,(OCISnapshot *) NULL, (ub4) OCI_DEFAULT); //执行SQL语句</p>
<p>5、结束会话断开数据库连接<br>OCILogoff( m_svchp, m_errhp );</p>
<p>6、断开与数据源的连接，释放句柄<br>OCIServerDetach( m_srvhp, m_errhp, OCI_DEFAULT ); //断开与数据源的连接<br>OCIHandleFree((dvoid *) m_stmthp, OCI_HTYPE_STMT); //释放句柄<br>OCIHandleFree((dvoid *) m_svchp, OCI_HTYPE_SVCCTX);<br>OCIHandleFree((dvoid *) m_srvhp, OCI_HTYPE_SERVER);<br>OCIHandleFree((dvoid *) m_errhp, OCI_HTYPE_ERROR)<br>3.7生成可执行文件（两种方法）<br>(1)同普通的C程序：<br>&nbsp;&nbsp; gcc -o exampled &#8211;I. &#8211;I$(ORACLE_HOME)/precomp/public example.c</p>
<p>(2)利用Oracle自带的Make文件：<br>首先将$ORACLE_HOME/rdbms/demo/demo_rdbms.mk文件copy到OCI源程序所在的目录，将源文件编译为目标文件：<br>#gcc &#8211;c example.o -I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/network/public -I$(ORACLE_HOME)/rdbms/public/ example.c<br>然后用命令：#make -f demo_rdbms.mk build OBJ*=**ample.o EXE=exampled，exampled就为生成的可执行文件</p>
</span></span>
<img src ="http://www.cppblog.com/ietj/aggbug/142533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ietj/" target="_blank">一路风尘</a> 2011-03-23 00:10 <a href="http://www.cppblog.com/ietj/articles/142533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle常用的OCI函数</title><link>http://www.cppblog.com/ietj/articles/142532.html</link><dc:creator>一路风尘</dc:creator><author>一路风尘</author><pubDate>Tue, 22 Mar 2011 16:09:00 GMT</pubDate><guid>http://www.cppblog.com/ietj/articles/142532.html</guid><wfw:comment>http://www.cppblog.com/ietj/comments/142532.html</wfw:comment><comments>http://www.cppblog.com/ietj/articles/142532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ietj/comments/commentRss/142532.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ietj/services/trackbacks/142532.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一． Oracle oci工具包安装：&nbsp;$ORACLE_HOME\BIN:执行文件和help文件&nbsp;$ORACLE_HOME\OCI\INCLUDE:头文件&nbsp;$ORACLE_HOME\OCI\LIB\BC:&nbsp; for Borlanf C++的OCI库&nbsp;$ORACLE_HOME\OCI\LIB\MSVC:&nbsp; for MS Visual C++...&nbsp;&nbsp;<a href='http://www.cppblog.com/ietj/articles/142532.html'>阅读全文</a><img src ="http://www.cppblog.com/ietj/aggbug/142532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ietj/" target="_blank">一路风尘</a> 2011-03-23 00:09 <a href="http://www.cppblog.com/ietj/articles/142532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>