Linux下C连接Oracle数据库OCCI的若干问题

关于配置问题 由于我的电脑已经被师兄配置好了 故无需再配置

这里首先转载师兄的日志,在他的日志里有了十分详细的介绍。

Step 1 下载 安装

 http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html

注意下载时,一定要看好自己都系统是多少位的。

?
1
2
3
4
5
6
7
[root@congyuandong - centos instant_clientfor_linux_x86 - 64 ] # ls
oracle - instantclient11. 2 - basic - 11.2 . 0.3 . 0 - 1.x86_64 .rpm
oracle - instantclient11. 2 - devel - 11.2 . 0.3 . 0 - 1.x86_64 .rpm
oracle - instantclient11. 2 - odbc - 11.2 . 0.3 . 0 - 1.x86_64 .rpm
oracle - instantclient11. 2 - sqlplus - 11.2 . 0.3 . 0 - 1.x86_64 .rpm
[root@congyuandong - centos instant_clientfor_linux_x86 - 64 ] # rpm -ivh *.rpm
Preparing...                ########################################### [100%]

 上面都网站中有好多要安装的文件,我也不知道为什么要安装上面都四个文件。

安装好后进行测试,会出现下面这些文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[yts@ytsCentos ~]$ tree / usr / lib / oracle / 11.2 / client64 / lib /
/ usr / lib / oracle / 11.2 / client64 / lib /
| - - glogin.sql
| - - libclntsh.so - > libclntsh.so. 11.1
| - - libclntsh.so. 11.1
| - - libnnz11.so
| - - libocci.so - > libocci.so. 11.1
| - - libocci.so. 11.1
| - - libociei.so
| - - libocijdbc11.so
| - - libsqlplusic.so
| - - libsqlplus.so
| - - libsqora.so. 11.1
| - - ojdbc5.jar
| - - ojdbc6.jar
| - - ottclasses. zip
` - - xstreams.jar
 
0 directories, 15 files

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[yts@ytsCentos ~]$ tree / usr / include / oracle / 11.2 / client64 /
/ usr / include / oracle / 11.2 / client64 /
| - - ldap.h
| - - nzerror.h
| - - nzt.h
| - - occiAQ.h
| - - occiCommon.h
| - - occiControl.h
| - - occiData.h
| - - occi.h
| - - occiObjects.h
| - - oci1.h
| - - oci8dp.h
| - - ociap.h
| - - ociapr.h
| - - ocidef.h
| - - ocidem.h
| - - ocidfn.h
| - - ociextp.h
| - - oci.h
| - - ocikpr.h
| - - ocixmldb.h
| - - ocixstream.h
| - - odci.h
| - - oratypes.h
| - - orid.h
| - - ori.h
| - - orl.h
| - - oro.h
| - - ort.h
` - - xa.h
 
0 directories, 29 files

 上面展现的两个目录是occi进行数据库操作时,所用到都库。因为我的电脑是64位系统,因此会有client64目录,如果是32位系统,则是client目录。

编写程序进行测试。

复制代码
include <iostream>
#define LINUXOCCI //避免函数重定义错误
#include <occi.h>
using namespace std;
using namespace oracle::occi;
int main()
{
   Environment *env=Environment::createEnvironment(Environment::DEFAULT);
   cout<<"success"<<endl;
   string name = "chezai";
   string pass = "Apple123";
   string srvName = "222.27.255.110:1521/ORCL.168.1.126";
   try
   {
     Connection *conn = env->createConnection(name, pass,srvName);
      cout<<"conn success"<<endl;
      env->terminateConnection(conn);
   }
   catch(SQLException e)
   {
      cout<<e.what()<<endl;
       return -1;
   }
   Environment::terminateEnvironment(env);
   cout<<"end!"<<endl;
   return 0;
}
复制代码

进行编译。

[yts@ytsCentos test]$ g++ testOracle.cpp -o testOracle -I/usr/include/oracle/11.2/client64/ -L/usr/lib/oracle/11.2/client64/lib/ -locci -lnnz11 -lclntsh

编译时需要引入相应都库,其中-I/path 后面接的路径(path)就是设置要是搜索相关的include文件的目录。-L/path 后面接都路径(path)就是设置搜索函数库文件(本例子中的libocci.so,libnnz11.so,libclntsh.so)的目录。其中-locci的含义如下:-l是要加入某个函数库(library)的意思,occi是libocci.so的意思,其他两个含义相同。

如果不希望每次编译都时候都像上面这样繁琐的话,可以进行如下两步改变。

首先,添加环境变量。

export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/oracle/11.2/client64/
export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib/oracle/11.2/client64/lib/

在.bashrc文件中添加玩上诉两个环境变量后,不要忘了souce一下,否则上面都环境变量不能马上生效。

其次,编写makefile文件。

main:testOracle.o
    g++ -o testOracle testOracle.o -locci -lnnz11 -lclntsh

这样,在编译时只需要如下操作。

[yts@ytsCentos test]$ make
g++ -o testOracle testOracle.o -locci -lnnz11 -lclntsh

这样,编译即可成功。

编译成功后,看看执行都效果。

[yts@ytsCentos test]$./testOracle
. /testOracle : error while loading shared libraries: libocci.so.11.1: cannot open shared object file : No such file or directory

此时会报错。

原因是缺少了LD_LIBRARY_PATH环境变量

添加环境变量。

export LD_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib/:$LD_LIBRARY_PATH

继续执行,报错

[yts@ytsCentos test]$./testOracle
success
ORA-12162: TNS:net service name is incorrectly specified

通过添加环境变量解决。

export ORACLE_SID=orcl

继续执行,仍然报错

[yts@ytsCentos test]$ ./testOracle
success
ORA-21561: OID generation failed

通过修改hosts文件解决。

复制代码
[yts@ytsCentos test]$ hostname
ytsCentos
[yts@ytsCentos test]$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.120 ytsCentos
[yts@ytsCentos test]$ 
复制代码

在文件中添加一行192.168.1.120 ytsCentos

这样再执行就能够成功。

但是当我进行另一段代码操作时出现下面的问题。

代码:

复制代码
 1 #include<iostream>
 2 #include<cstring>
 3 #include<vector>
 4 #include<occi.h>
 5 #include<fstream>
 6 #include<ctime>
 7 #include<stdio.h>
 8 #include<stdlib.h>
 9 
10 using namespace oracle::occi;
11 using std::vector;
12 using namespace std;
13 
14 class connDBA
15 {
16 private:
17     Environment *env;   
18     Connection *conn;   
19     Statement *stmt;
20 public:
21     connDBA(string user,string pass,string db){
22         env = Environment::createEnvironment (Environment::DEFAULT);     
23         conn = env->createConnection (user, pass, db);
24     }
25     ~connDBA(){
26         env->terminateConnection(conn);     
27         Environment::terminateEnvironment(env);
28     }
29 
30 
31     //Oracle Block Save Example!!
32     void selectTest3(string name){
33 
34         Statement *stmt = NULL;
35         ResultSet *rs = NULL;
36      string sql = "select * from carlist where userid ='"+name+"'";
37     //string sql = "select * from carlist where carid ='0011001100110000'";
38         try{
39             stmt = conn->createStatement(sql);
40         }
41         catch (SQLException& ex){
42             cout << ex.getMessage();
43         }
44 
45         if(stmt){
46         try{
47       //cout<<"stmt"<<endl;
48            rs = stmt->executeQuery();
49         }
50         catch (SQLException& ex){
51            cout << ex.getMessage();
52         }
53         while (rs->next()) {
54             //string userid = rs->getString(1);
55             string carid = rs->getString(2);
56             //cout<<carid<<endl
57             cout<<carid<<endl;
58         }
59         stmt->closeResultSet(rs);
60     }
61         conn->terminateStatement(stmt);
62    }
63 };
64 
65 int main(){
66     string user = "chezai";
67     string pass = "Apple123";
68     string db = "222.27.255.110/ORCL.168.1.126";
69 
70     connDBA *demo;
71 
72     try{
73         demo = new connDBA(user,pass,db);
74         cout<<"connect success"<<endl;
75     }catch (SQLException e){
76         cout<<e.getMessage()<<endl;
77         return -1;
78     }
79 
80        demo->selectTest3("红牛2");
81 
82 }
复制代码

错误情况是上面都所有操作都执行成功,但是从数据库中检索出来都数据总是为空,但是数据库中却有这样的数据。经过网上查询是编码的问题,需要配置NLS_LANG环境变量,而且必须与数据库的字符编码一致,否则会出现乱码。

设置方式为:

export NLS_LANG=AMERICAN_AMERICA.UTF8

这样就能够正常的查询数据啦。

[yts@ytsCentos test]$ ./testOracle 
success
conn success
end!
基本遇到的问题都在这里了 要主要编译命令以及修改hosts文件的权限问题,要用root账户才能修改 ,把当前电脑的hostname添加进去

你可能感兴趣的:(oracle,C++,linux,数据库)