ITPub博客

首页 > 数据库 > Oracle > Fedora13 下使用 OTL 访问 Oracle 数据库

Fedora13 下使用 OTL 访问 Oracle 数据库

Oracle 作者:洪义泰和 时间:2014-01-25 18:03:35 0 删除 编辑
由于 OTL 访问 Oracle 实际是使用 OCI API ,所以一般来说需要用户安装 Oracle Client 。

1.在 Oracle 官网的如下位置
  Oracle Technology Network > Database > Database Features > Database Instant Client
  http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html
  下载 Instant Client for Linux x86 (根据你实际的开发环境的操作系统来定)

  测试用 Oracle 数据库版本信息如下:
  Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
  PL/SQL Release 11.2.0.2.0 - Production
  CORE 11.2.0.2.0 Production
  TNS for Linux: Version 11.2.0.2.0 - Production
  NLSRTL Version 11.2.0.2.0 - Production

  对应的 Instant Client 版本也为 11.2.0.2.0 

2.安装 Instant Client 与开发相关的三个安装包:
  注:以下安装包均要以 root 身份来安装!
  oracle-instantclient11.2-basic-11.2.0.2.0.i386.rpm
  运行 OCI/OCCI/JDBC-OCI 应用程序所需的全部文件。
  # rpm -i oracle-instantclient11.2-basic-11.2.0.2.0.i386.rpm
  查看安装的信息:
  # rpm -qlp oracle-instantclient11.2-basic-11.2.0.2.0.i386.rpm
  /usr/lib/oracle/11.2/client/bin/adrci
  /usr/lib/oracle/11.2/client/bin/genezi
  /usr/lib/oracle/11.2/client/lib/libclntsh.so.11.1
  /usr/lib/oracle/11.2/client/lib/libnnz11.so
  /usr/lib/oracle/11.2/client/lib/libocci.so.11.1
  /usr/lib/oracle/11.2/client/lib/libociei.so
  /usr/lib/oracle/11.2/client/lib/libocijdbc11.so
  /usr/lib/oracle/11.2/client/lib/ojdbc5.jar
  /usr/lib/oracle/11.2/client/lib/ojdbc6.jar
  /usr/lib/oracle/11.2/client/lib/xstreams.jar
    
  oracle-instantclient11.2-devel-11.2.0.2.0.i386.rpm
  使用 Instant Client 开发 Oracle 应用程序所需的头文件及一个示例 makefile 文件。
  # rpm -i oracle-instantclient11.2-devel-11.2.0.2.0.i386.rpm
  查看安装的信息:
  # rpm -qlp oracle-instantclient11.2-devel-11.2.0.2.0.i386.rpm 
  /usr/include/oracle/11.2/client/ldap.h
  /usr/include/oracle/11.2/client/nzerror.h
  /usr/include/oracle/11.2/client/nzt.h
  /usr/include/oracle/11.2/client/occi.h
  /usr/include/oracle/11.2/client/occiAQ.h
  /usr/include/oracle/11.2/client/occiCommon.h
  /usr/include/oracle/11.2/client/occiControl.h
  /usr/include/oracle/11.2/client/occiData.h
  /usr/include/oracle/11.2/client/occiObjects.h
  /usr/include/oracle/11.2/client/oci.h
  /usr/include/oracle/11.2/client/oci1.h
  /usr/include/oracle/11.2/client/oci8dp.h
  /usr/include/oracle/11.2/client/ociap.h
  /usr/include/oracle/11.2/client/ociapr.h
  /usr/include/oracle/11.2/client/ocidef.h
  /usr/include/oracle/11.2/client/ocidem.h
  /usr/include/oracle/11.2/client/ocidfn.h
  /usr/include/oracle/11.2/client/ociextp.h
  /usr/include/oracle/11.2/client/ocikpr.h
  /usr/include/oracle/11.2/client/ocixmldb.h
  /usr/include/oracle/11.2/client/ocixstream.h
  /usr/include/oracle/11.2/client/odci.h
  /usr/include/oracle/11.2/client/oratypes.h
  /usr/include/oracle/11.2/client/ori.h
  /usr/include/oracle/11.2/client/orid.h
  /usr/include/oracle/11.2/client/orl.h
  /usr/include/oracle/11.2/client/oro.h
  /usr/include/oracle/11.2/client/ort.h
  /usr/include/oracle/11.2/client/xa.h
  /usr/lib/oracle/11.2/client/lib/libclntsh.so
  /usr/lib/oracle/11.2/client/lib/libocci.so
  /usr/lib/oracle/11.2/client/lib/ottclasses.zip
  /usr/share/oracle/11.2/client/cdemo81.c
  /usr/share/oracle/11.2/client/demo.mk
  /usr/share/oracle/11.2/client/occidemo.sql
  /usr/share/oracle/11.2/client/occidemod.sql
  /usr/share/oracle/11.2/client/occidml.cpp
  /usr/share/oracle/11.2/client/occiobj.cpp
  /usr/share/oracle/11.2/client/occiobj.typ
  /usr/share/oracle/11.2/client/ott
  
  oracle-instantclient11.2-sqlplus-11.2.0.2.0.i386.rpm
  使用 Instant Client 运行 SQL×Plus 所需的库及可执行程序。
  # rpm -i oracle-instantclient11.2-sqlplus-11.2.0.2.0.i386.rpm
  查看安装的信息:
  # rpm -qlp oracle-instantclient11.2-sqlplus-11.2.0.2.0.i386.rpm
  /usr/bin/sqlplus
  /usr/lib/oracle/11.2/client/bin/sqlplus
  /usr/lib/oracle/11.2/client/lib/glogin.sql
  /usr/lib/oracle/11.2/client/lib/libsqlplus.so
  /usr/lib/oracle/11.2/client/lib/libsqlplusic.so

3.创建 TNS 配置目录及配置文件:
  TNS 是 Oracle Net 的一部分,专门用来管理和配置 Oracle 数据库和客户端连接的一个工具,
  在大多数情况下客户端和数据库要通讯,必须配置 TNS !
  当然,在少数情况下,不用配置 TNS 也可以连接 Oracle 数据库,如:通过 JDBC 。
  如果通过 TNS 连接 Oracle 数据库,就必须安装 Oracle 客户端程序,如上:oracle-instantclient
  
  进入到 /usr/lib/oracle/11.2/client 目录下,创建目录 NETWORK 目录,
  再进入 NETWORK 目录下,创建目录 ADMIN 目录,
  再进入 ADMIN 目录下,创建名为 tnsnames.ora 的文本文件,内容如下:
  # tnsnames.ora Network Configuration File: /usr/lib/oracle/11.2/client/NETWORK/ADMIN/tnsnames.ora
  # Generated by Oracle configuration tools.

  testdb = 
  (
       DESCRIPTION =
       (
            ADDRESS_LIST = 
            (
                 ADDRESS = 
                 (
                      PROTOCOL = TCP
                 )
                 (
                      HOST = 192.19.13.129
                 )
                 (
                      PORT = 1521
                 )
            )
       )
       (
            CONNECT_DATA = 
            (
                 SERVICE_NAME = orcl
            )
       )
  )

  注:PROTOCOL     指出数据库网络协议;
    HOST         指出数据库网络地址;
    PORT         指出数据库网络端口;
    SERVICE_NAME 指出数据库名;

4.配置环境变量:
  Oracle Client 的安装根目录:
  $ export ORACLE_HOME=/usr/lib/oracle/11.2/client

  Oracle Client 的相关共享库:
  $ export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

  sqlplus/genezi/adrci 可执行程序所在目录:
  $ export PATH=$PATH:$ORACLE_HOME/bin

  服务配置目录:
  $ export TNS_ADMIN=$ORACLE_HOME/NETWORK/ADMIN

5.使用 sqlplus 连接 Oracle 数据库:
  格式:
  $ sqlplus 用户名/密码@TNS名
  例如:
  $ sqlplus wzhnsc/123456@testdb
  出现如下信息说明数据库连接成功,OCI 的开发环境基本上也就搭建好了:
  SQL*Plus: Release 11.2.0.2.0 Production on Thu Jan 23 17:57:15 2014
  Copyright (c) 1982, 2010, Oracle.  All rights reserved.

  ???: 
  Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
  With the Partitioning, OLAP, Data Mining and Real Application Testing options

  SQL> 

  注:以下为查看当前数据库名:
    数据库名是在安装数据库、创建新的数据库、创建数据库控制文件、修改数据结构、
    备份与恢复数据库时都需要使用到的。
  SQL> select name from v$database;

  NAME
  ---------
  ORCL

  注:以下为查看当前数据库实例名:
    数据库实例名是用于和操作系统进行联系的标识,
    就是说数据库和操作系统之间的交互用的是数据库实例名。
  SQL> select instance_name from v$instance;

  INSTANCE_NAME
  ----------------
  orcl

  注:以下为查看 Oracle 数据库版本:
  SQL> select * from v$version;

  BANNER
  --------------------------------------------------------------------------------
  Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
  PL/SQL Release 11.2.0.2.0 - Production
  CORE 11.2.0.2.0 Production
  TNS for Linux: Version 11.2.0.2.0 - Production
  NLSRTL Version 11.2.0.2.0 - Production

6.在 OCI 应用程序中指出头文件与动态库的地址:
  -I/usr/include/oracle/11.2/client
  -L/usr/lib/oracle/11.2/client/lib -lclntsh

7.如何使用 OTL :
  OTL 是一个数据库访问模板库,支持绝大部分数据库访问。
  OTL 是 C++ 写的,基于模板,只有 otlv4.h 这一个头文件,大小只有800多KB。

  官方网址:http://otl.sourceforge.net

  1>使用 oracle 时候要定义如下面宏:
    #define OTL_ORA11G // 表示使用 Oracle 11g 的 OCI
    #define OTL_ORA9I  // 表示使用 Oracle 9i  的 OCI

    使用大整数时,定义如下宏:
    #define OTL_BIGINT __int64

  2>初始化 OTL :
    otl_connect m_db;

    // 用于设置 Oracle 的 NLS_LANG 环境变量,
    // 这样可以避免读取 Oracle 的中文数据记录时出现乱码
    _putenv( const_cast( "NLS_LANG=SIMPLIFIEDCHINESE_CHINA.ZHS16GBK" ) );

    // 以线程安全模式初始化 OCI 环境
    m_db.otl_initialize( 1 );

  3>连接 Oracle 数据库:
    // 使用该方式连接 Oracle 数据库需要配置 tnsnames.ora ,如上 3. 所述内容
    // 连接 Oracle 数据库字符串的一般格式:
    // 用户名/密码@TNS名
    std::string strConnectOracle = "wzhnsc/123456@testdb";

    或
    // 如下字符串中的 协议/IP/端口/数据库名 在实际应用中可以传参赋值
    std::string strTNSName = "( DESCRIPTION = "
                             "( ADDRESS = ( PROTOCOL = TCP )( HOST = 192.19.13.129 )( PORT = 1521 ) )"
                             "( CONNECT_DATA = ( SERVICE_NAME = orcl ) ) )"
    std::string strConnectOracle = "wzhnsc/123456@" + strTNSName;
    
    try
    {
         m_db.rlogon( strConnectOracle, // 连接 Oracle 数据库字符串
                      0 );              // 零(0) - 不自动提交,壹(1) - 要自动提交
    }
    catch ( otl_exception& e )
    {
         printf( "Oracle connect error( msg: %s, stm_text: %s, sqlstate: %s, var_info: %s )", 
                 e.msg, 
                 e.stm_text, 
                 e.sqlstate, 
                 e.var_info );
    }

  4>执行 SQL 语句:
    // 返回 SQL 执行后所影响的记录条数,如:
    // 执行 DELETE 操作后,返回删除了多少行,执行 UPDATE 操作后,返回更新了多少行
    long lResult = otl_cursor::direct_exec( m_db,                      // OCI 连接器
                                            szSQL,                     // SQL 语句字符串
                                            otl_exception::disabled ); // 禁止 OTL 异常

  5>流化读取数据记录:( OTL 的亮点就在于可以像 C++ 的 stream 操作那样读写数据记录)
    // 注意:如下 SQL 语句中的,以冒号(:)开头的均为占位变量,冒号则被称为占位符。
    //    :age1 和 :age2 就是以冒号占位符为前缀的占位变量。
    //    一个占位变量可以在相同的 SQL 语句中多次出现。
    //    Oracle 的占位变量命名习惯不同于 ODBC 或 DB2-CLI ,格式如下:
    //    冒号(:)+占位变量名+尖括号括起的类型(如:)
    //    具体参见:http://otl.sourceforge.net/otl3_bind_variables.htm
    //    OTL 4.0 有一个小型分析器会把占位变量动态的用输入流操作(<<)传入的值替换掉。
    const char* szSQL = "SELECT id, user, age "
                        "FROM users" 
                        "WHERE age >= :age1 AND age <= :age2";  
    try  
    {  
         otl_stream o( 1000,   // 缓冲区大小(记录条数)
                       szSQL,  // SQL 语句字符串
                       m_db ); // OCI 连接器
         // 25 将替换 :age1
         // 45 将替换 :age2
         // 即按顺序替换!
         o << 25 << 45;  
   
         long lID  = 0;
         long lAge = 0;  
         char caUserName[80];  

         while ( !o.eof() )  
         {
              o >> lID >> caUserName >> lAge;

              printf( "ID = %d, UserName = %s, Age = %d ", 
                      lID,
                      caUserName, 
                      lAge );
         }

         // 前面调用 rlogon 函数时,第二个参数:
         // 如果为零(0) - 不自动提交时,这里要显示调用 commit 函数来提交。
         m_db.commit();
    }  
    catch( otl_exception& e )  
    {  
         printf( "SELECT error( msg: %s, stm_text: %s, sqlstate: %s, var_info: %s )", 
                 e.msg, 
                 e.stm_text, 
                 e.sqlstate, 
                 e.var_info );  
    }
  
  多线程下使用 OTL 时几个注意的地方:
  1)static int otl_connect::otl_initialize( const int threaded_mode = 0 );
    如果在多线程环境下使用,参数 threaded_mode 设置为壹(1)。

    注意:即使设置为1并不代表就是线程安全(thread-safe)。

    实际上 OTL 并不是线程安全的,一个 otl_connect 只能同时被一个线程使用,
    如果在多线程环境下使用 OTL ,需要自己保证 otl_connect 对象的线程安全。

 2)otl_stream_pool
   OTL 支持 stream pool ,就是一个池,
   在一个 otl_stream close 时,把它放到池中,下次访问时可以从池中获取,
   实现最快重用,提高程序性能。

   注意:otl_stream_pool 是 otl_connect 的一个成员,
      所以要在 otl_connect 解锁之前执行 otl_stream.close 。
      即使不使用 otl_stream_pool ,也要在 otl_connect 解锁之前执行 otl_stream.close 。
<!-- 正文结束 -->

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23424649/viewspace-1115079/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2010-03-01