`
qdujunjie
  • 浏览: 110399 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

OCCI基础教程(一)

    博客分类:
  • OCCI
阅读更多

 

前几天,偶然知道了一个新名词:OCCI,这是虾米东东呢?找了时间看了一下,原来是一套oracle提供的访问oracle数据库的C++接口,用过微软数据库的朋友马上会联想到一个东西,那就是DAO,不错,这东西的原理和DAO是一样的,下面就让我们来看一下OCCI把。(DAO就是Data Access Object的缩写,也是一套访问数据库的库,IT界缩写词很多,有可能你在用着都不自知,这没有关系)

 

 

因为我是直接从oracle网站上查看的,在下面这个地址,有两个压缩包,里面包含了OCCI的演示代码,我们就从这里开始分析吧:

 

http://www.oracle.com/technology/global/cn/sample_code/tech/occi/index.html

 

我们可以先从第二个压缩包的内容开始看起,就是这个包:

 

occiplsql.tar.tar

 

我们下载之后,解压缩,包含三个文件,其中一个是

 

storedproc.cpp

 

我们就从她开始看吧。(其实这个文件是一个PL/SQL的演示程序,里面使用了三种执行存储过程的办法,下面就会讲到;另外,这个程序需要用到一些存储过程,在解压得到的occiplsql_readme.txt文件中有详细的描述,使用schema.sql在自己的数据库中创建存储过程,这里省略)

 

让我们一行一行代码来分析

 

 

 

首先,它调用了文件所需头文件:

 

#include <iostream>
#include <string>
#include <vector>

#include <occi.h>

  

 

 

 

这里最重要的就是occi.h了,这一看就是occi库文件的头文件,一般我们后面基本上都要导入这个头文件,无需赘言。

 

然后代码紧跟着的就是一个main()函数,让我们看一看下面的代码:

 

 

 

   //initialize in object mode since we are accessing VARRAY types
   Environment *env = Environment::createEnvironment(Environment::OBJECT);
   Connection *conn = env->createConnection("scott","tiger");
   Statement *stmt = conn->createStatement();

 

 

 

这三段代码是调用OCCI的基础,初始环境,建立连接,并且创造一个Statement来对数据库进行操作。

 

 

下面看看他如何执行sql语句吧:

 

 

 

 

    //create anonymous block for executing stored proc/function
    stmt->setSQL("begin OCCIDEMO1.GetBookDetails(:1, :2, :3, :4, :5); end;");
    int id = 1;//book to retrieve

    //pass IN parameters by setXXX(), indicate OUT parameters 
    //by registerOutParam
    stmt->setNumber(1, id);//1 - IN - Id
    stmt->registerOutParam(2, OCCISTRING, 100); //2 - OUT - title,max=100
    stmt->registerOutParam(3, OCCIDOUBLE); //3 - OUT - price
    stmt->registerOutParam(4, OCCIDATE); //4 - OUT - pubdate
    stmt->registerOutParam(5, OCCIVECTOR, 0,
         "SCOTT.KEYWORDSLIST"); //5 - OUT - keywords(varray)

    stmt->execute(); //execute procedure

 

 

很简单,不是吗?这里调用了存储过程,注册了几个输出函数。这些和.NET平台的存储过程调用很像,尤其跟JSP中的数据库调用很像(简直一摸一样)。注意,里面的输出函数调用了OCCI的变量,就是OCCISTRING,OCCIDOUBLE等等,以OCCI*形式的变量。

 

然后我们往下看:

 

    //get the OUT parameters
    string title = stmt->getString(2);
    double price = stmt->getDouble(3);
    Date pubdate = stmt->getDate(4); //OCCI Date class
    vector<string> keywords;
    //there are overloaded getVector methods for each vector<T>
    getVector(stmt, 5, keywords);

 

 

 

 

这里注释的很清楚,得到刚才我们定义的存储过程输出变量的输出值,我们只需从Statement中取出结果就行了,无需赘言。

 

然后下面执行了一些输出函数,打印我们的结果:

 

    cout << "Book Details : " <<  title << " " << price << " " << 
         pubdate.toText() << endl;
    cout << "Keywords : ";
    for (int i = 0 ; i < keywords.size(); i++)
       cout << keywords[i] << ",";
    cout << endl;

    cout << "******Calling GetBookList******" << endl;

  

 

 

 

 

然后我们来看下面的第二个存储过程,这个和第一个是不同(废话),哪里不同呢?我们可以看一下他的注释:

 

//Stored Function 2 - shows PL/SQL tables and function returning value

 

使用函数返回值得到表

 

/* To pass/retrieve PL/SQL tables use setDataBufferArray method :-
     void setDataBufferArray(unsigned int paramIndex,
        void *array, Type type, ub4 arraySize, ub4 *arrayElements,
        sb4 elementSize, ub2 *elementLengths, sb2 *ind = NULL, ub2 *rc = NULL)

   After the execute, the buffer will contain OUT values
*/

 

第一句,使用setDataBufferArray函数来传递和恢复 PL/SQL表

 

看看我们第一个存储过程,是直接传递的变量和得到结果,姑且称之为“直接法”,而第二个演示的方法就是使用Statement自带的函数setDataBufferArray来进行操作了。

 

注意,这里的注释同时也告诉了我们将要用到的setDataBufferArray函数的原型,大家可以稍微看一下,下面会用到。

 

下面我们来看看第二个存储过程的代码

 

首先,进行了各种变量的定义:

 

    stmt->setSQL("begin :1 := OCCIDEMO1.GetBookList(:2, :3); end;");
    int idlist[10];
    char booklist[10][200];
    ub4 inelems=3,outelems=0;
    ub2 outelemlens[10], inelemlens[10];
    idlist[0] = 1;idlist[1] = 2;idlist[2] = 3;//book Ids 1,2,3
    inelemlens[0] = inelemlens[1] = inelemlens[2] =  sizeof(int);

 

 

 

这里,就定义了setDataBufferArray需要用到的让人困惑的ub4,ub2等类型的变量,这些其实就是用来buffer我们的结果的。

 

然后下面正式开始使用setDataBufferArray来进行操作:

 

 

    stmt->setDataBufferArray(2, idlist, OCCIINT, 10, &inelems,
          sizeof(int), inelemlens);//2 - IN - TABLE OF NUMBER
    stmt->setDataBufferArray(3, booklist, OCCI_SQLT_STR, 10, &outelems,
          200, outelemlens);//3 - OUT - TABLE OF VARCHAR2
    stmt->registerOutParam(1, OCCIINT); //1 - Function return value

    stmt->execute(); //execute the function

  

 

 

 

这里我们可以看到,用到了两次setDataBufferArray,我前面已经说过setDataBufferArray就是用来buffer我们的变量(还有值),最后的结果被contain在了outelemlens中。(这些在程序的注释中都提到了)

 

之后我们就可以取得返回的值,向下面这样:

 

    int ret = stmt->getInt(1);//Function return value
    cout << "Function return : " << ret << endl;

    cout << "Elements returned : " << outelems << endl;
    for (int j = 0; j < outelems; j++)
      cout << booklist[j] << "[" << outelemlens[j] << "]" << endl;

    cout << "******Calling SearchBooks******" << endl;

 

 

 

好了,这就是使用了setDataBufferArray的用法。

 

下面我们来看例子中的最后一个用法:

 

//Stored Proc 3 - returns a REF cursor for a query

 

说得很清楚,就是返回一个可以被我们用来操作的REF cursor (引用游标),这样我们就可以操作集合数据了,这个也很简单,做过数据库的都知道,简单看一下吧:

 

 

    stmt->setSQL("begin OCCIDEMO1.SearchBooks(:1, :2); end;");
    //for IN/OUT, input with setXXX, do not call registerOutParam
    stmt->setString(1, "Databases"); //1 - IN/OUT - varchar
    stmt->setMaxParamSize(1, 100);//max param size for string parameter
    stmt->registerOutParam(2, OCCICURSOR);//2 - OUT - Ref Cursor
  
    stmt->execute();//execute stored procedure 

 

 

 

首先,这些都是相同的,同样是规定了输入和输出变量,然后执行。

 

 

    cout << "Searched using keyword: " << stmt->getString(1) << endl;
    ResultSet *rs = stmt->getCursor(2);//use ResultSet to fetch rows
    //we know cursor has 1 varchar column in Select, use getString()
    while (rs->next())
      cout << "Book : " << rs->getString(1) << endl;

    stmt->closeResultSet(rs);

 

 

 

 

然后,这里用到了Statement的getCursor将结果赋值给一个ResultSet(结果集),之后我们就可以遍历返回的数据了。

 

 

到此为止,就完成了对OCCI操作PL/SQL语言示例的解释(好像没有讲什么东西,别怪我,因为确实很简单^_^,就是我们每天使用到的,而且示例也很简单,不过这很好,simple is beautiful)。

 

 

好了,到这里就结束了,我们要进行收尾工作,像下面这样:

 

   conn->terminateStatement(stmt);

   env->terminateConnection(conn);
   Environment::terminateEnvironment(env);

  

 

将我们用到的这三个变量倒序释放掉,这应该是个好习惯。

 

其实整个这部分都是用到了异常处理,我们在这里没有提及,大家可以自行研究。

 

到这里,对OCCI的简单数据库操作就结束了。

 

如果有时间,我们将在教程2中讲一下另一个压缩包的内容。并且将所有涉及到的代码都调试一下,看看实际中是怎样的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    OCCI 样例 教程

    **OCCI 编程基础** 1. **连接管理**:使用 `Environment` 类创建和管理数据库连接。创建环境对象,然后在环境中创建连接,如 `Environment::createEnvironment()` 和 `Connection::connect()`。 2. **游标和陈述**:...

    occi使用手册(11g Release 1 (11.1))

    《OCCI使用手册(11g Release 1 (11.1))》是一份详尽的指南,专为那些希望深入理解并有效利用Oracle C++ Call Interface (OCCI)的开发者而编写。OCCI是Oracle数据库的一个高性能、低级接口,它允许C++应用程序直接...

    oracle occi资料大全

    4. **OCCI使用指南**:这可能是一份详细的操作手册或者教程,涵盖了OCCI的各种功能和使用场景,包括连接池的管理、异常处理、性能优化等方面的指导,是学习和使用OCCI的重要参考资料。 5. **官网的OCCI书籍**:这...

    OCCI 用户指南和OCCI源码

    Oracle Call Interface (OCCI) 是 Oracle 公司提供的一种C++接口,用于访问和操作 Oracle 数据库。OCCI 提供了一种高效、类型安全且面向对象的方式来与 Oracle 数据库进行交互,使得开发者能够轻松地在 C++ 应用程序...

    OCCI资料_例子

    Oracle Call Interface (OCCI) 是Oracle数据库提供的一种C++接口,允许开发者直接使用C++语言进行数据库编程。这个“OCCI资料_例子”压缩包显然包含了一系列与OCCI相关的资源,包括基本介绍、编程指南、使用手册以及...

    OCCI接口调用简介

    **OCCI的基础** OCCI自9i版本开始引入,并在后续版本中不断得到增强。它由一系列精心设计的C++类和接口组成,提供了对SQL/PLSQL的执行支持,以及对用户定义类型(UDT)对象的无缝操作。OCCI还支持所有Oracle数据...

    OCCI简介(附实例)

    Environment 对象是 OCCI 程序的基础类,所有的 OCCI 对象的建立都是依计 Environment 对象来创建的。创建 Environment 对象的方法如下所示: Environment *env = Environment::createEnvironment(); 终止 ...

    VC++ OCCI 操作 ORACLE

    - 首先,需要创建一个Environment对象,它是所有OCCI对象的基础。Environment::createEnvironment()方法用于创建环境对象,可以设置不同的运行模式,如互斥线程(THREADEC_MUTEXED)或并行线程(THREADEC_UMMUTEXED...

    OCCI 11.2API文档

    OCCI API提供了一种高效的数据库操作方式,尤其适用于需要高性能数据处理的应用程序。OCCI 11.2是这一系列API的11.2版本,针对Oracle 11g Release 2(11.2)数据库版本。 在进行Oracle项目开发时,OCCI API文档是...

    oracle occi

    OCCI自Oracle 9i版本中引入,拥有不断增长的用户基础,提供了一系列封装良好的类和接口,旨在方便使用,支持关系型和对象关系型访问,并具有可扩展性特点。OCCI的特点是采用标准C++语言和面向对象设计,使得应用程序...

    oracle OCCI使用详解

    Oracle OCCI,全称为Oracle Call Interface for C++,是Oracle公司提供的一种C++接口,用于与Oracle数据库进行交互。OCCI使得开发人员能够利用C++的强大功能和面向对象特性来编写高效、健壮的数据库应用。在Oracle...

    occi program guide

    综上所述,Oracle C++ Call Interface (OCCI) 作为一种强大的API,不仅为C++开发者提供了与Oracle数据库交互的能力,而且也为企业级应用的开发提供了坚实的基础。通过深入理解和掌握OCCI的相关知识,开发者可以更加...

    OCCI学习资料

    Oracle Call Interface (OCCI) 是Oracle数据库提供的一种C++接口,用于开发人员在C++应用程序中与Oracle数据库进行交互。OCCI提供了丰富的类库和函数,使得开发者能够方便地执行SQL语句、处理结果集、管理事务等。...

    OCCI添加Oracle特殊数据字段类型

    OCCI(Oracle C++ Call Interface)是一种基于 C++ 的 Oracle 数据库接口,允许开发者使用 C++ 语言访问 Oracle 数据库。OCCI 提供了一个强大且灵活的方式来访问 Oracle 数据库,支持多种数据类型,包括 Oracle 特殊...

    oracle-occi

    2. **环境(Environment)**:这是OCCI所有活动的基础,它定义了运行时的属性,如错误处理模式和内存管理策略。 3. **游标(Cursor)**:游标代表SQL语句的执行实例,允许应用程序一行一行地处理查询结果。`Oracle:...

    ODBC与OCCI对照

    ODBC(Open Database Connectivity)和...ODBC提供了一种标准接口,可以跨数据库系统使用,而OCCI是Oracle特有的,提供了更底层的访问和更高效的性能。选择哪种接口取决于项目需求,如兼容性、性能、易用性和特定功能。

    occi测试代码

    这是使用OCCI进行数据库操作的基础。 - **建立连接**: - `Connection* conn = env-&gt;createConnection(userName, passWord, connectString);`:使用提供的用户名、密码和连接字符串创建数据库连接。 - **创建语句...

    VC occi连接oracle 源代码

    首先,OCci是Oracle公司为C++开发者提供的一种更高级别的接口,它封装了低级别的OCI API,使得数据库操作更为简洁和面向对象。在VC项目中引入OCci,你需要包含必要的头文件,如`&lt;oci.h&gt;`,并链接相应的库文件,例如`...

    OCCI封装包 线程池

    OCCI封装包 线程池 对occi进行了封装 利用线程池方案

    OCCI说明文档

    **Oracle C++ Call Interface (OCCI)** 是Oracle为C++开发者提供的高级应用程序接口,它提供了一种高效、便捷的方式来访问Oracle数据库。相较于Oracle Call Interface (OCI),OCCI提供了更为简化且面向对象的API,...

Global site tag (gtag.js) - Google Analytics