由于 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/
,如需转载,请注明出处,否则将追究法律责任。