1. 程式人生 > >終於解決了Linux下執行OCCI程式一直報Error while trying to retrieve text for error ORA-01804錯誤

終於解決了Linux下執行OCCI程式一直報Error while trying to retrieve text for error ORA-01804錯誤

Linux 下執行OCCI程式,一直報如下錯誤:
Exception: Code - 1804, Message - Error while trying to retrieve text for error ORA-01804
之前也遇到了該錯誤,當時解決辦法是配置 ORACLE_HOME 環境變數。

(一) 安裝Oracle Instant Client

這次我使用的是 Oracle Instant Client 11.2.0.1.0 ,
下載地址:
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html
可以下載rpm包或者zip包進行安裝.


(1) rpm 包

若下載的是Version 11.2.0.1.0 版本的 rpm 包,
oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.rpm 
oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.rpm
oracle-instantclient11.2-devel-11.2.0.1.0-1.x86_64.rpm
使用如下命令進行安裝
rpm -ivh oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.rpm 
rpm -ivh oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient11.2-devel-11.2.0.1.0-1.x86_64.rpm
安裝完成後,
ORACLE Instant Client 相關的標頭檔案在 /usr/include/oracle/11.2/client64/下(sdk包中的),
庫檔案在 /usr/lib/oracle/11.2/client64/下(cliient64目錄下有 lib 和 bin兩個目錄.){sqlplus相關的配置在 (2) 中說明 }
配置如下環境變數: ~/.bashrc
export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export TNS_ADMIN=$ORACLE_HOME/network/admin
export NLS_LANG='simplified chinese_china'.ZHS16GBK
export LD_LIBRARY_PATH=$ORACLE_HOME/lib 
export PATH=$ORACLE_HOME/bin:$PATH


(2) zip 包

若下載的是Version 11.2.0.1.0 版本的 zip 包,則下載如下三個包
oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip
oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.zip  
oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.zip
使用如下命令進行解壓安裝
unzip  oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip
unzip  oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.zip  
unzip  oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.zip
例如最後解壓到目錄 /opt/oracle_instant_client/instantclient_11_2 下,目錄下的檔案和目錄如下

[root@localhost instantclient_11_2]# ls 
adrci genezi libclntsh.so.11.1 libocci.so.11.1 libocijdbc11.so libsqlplus.so ojdbc5.jar 
sdkSQLPLUS_README xstreams.jarBASIC_README glogin.sql libnnz11.so libociei.so 
libsqlplusic.sonetworkojdbc6.jar sqlplus sqlplus.sh

{ 標頭檔案在 sdk/include下,庫檔案在instantclient_11_2目錄下 }

{ network/admin目錄是我自己建立的,用於sqlplus連線資料庫,目錄下有一個檔案 tnsnames.ora,配置了資料庫連線,檔案內容如下:
ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.232.131)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
  
ORCL_XP =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.232.133)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  ) )
}


配置如下環境變數: ~/.bashrcexport 
export ORACLE_HOME=/opt/oracle_instant_client/instantclient_11_2
export TNS_ADMIN=$ORACLE_HOME/network/adminexport 
export NLS_LANG='simplified chinese_china'.ZHS16GBKexport 
export LD_LIBRARY_PATH=$ORACLE_HOME
export PATH=$ORACLE_HOME:$PATH
配置完畢後, source  ~/.bashrc
執行 sqlplus 命令即可連線資料庫進行操作,例如:
sqlplus /nolog
conn scott/tiger@orcl
安裝完畢!

(二) 編譯OCCI程式
編譯OCCI程式可以使用兩種方式:
(1) 方法一:使用 Oracle 11.2.0.1 資料庫軟體中自帶的 OCCI 相關庫和標頭檔案.
在一個安裝好Oracle 11.2.0.1 R2 資料庫的機器上拷貝occi相關標頭檔案和庫檔案到目錄 /opt/OCCI_11g_R2/include 和 /opt/OCCI_11g_R2/lib 下, 
標頭檔案:
mkdir  /opt/OCCI_11g_R2/include
cp -r /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/rdbms/public/*     /opt/OCCI_11g_R2/include/
庫檔案:
mkdir  /opt/OCCI_11g_R2/lib
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libclntsh.so.11.1    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libocci.so.11.1    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libocci11.a    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.so    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.a   /opt/OCCI_11g_R2/lib/
cd /opt/OCCI_11g_R2/lib
建立3個軟連結
ln -s libocci.so.11.1  libocci.so
ln -s libclntsh.so.11.1   libclntsh.so
ln -s libclntsh.so libclntsh.so.10.1  
[root@localhost lib]# ll
總計 69764
lrwxrwxrwx 1 root root       17 01-07 13:33 libclntsh.so -> libclntsh.so.11.1
lrwxrwxrwx 1 root root       12 01-07 13:33 libclntsh.so.10.1 -> libclntsh.so
-rwxr-xr-x 1 root root 48724689 01-07 12:58 libclntsh.so.11.1
-rw-r--r-- 1 root root 11595642 2012-01-07 libnnz11.a
-rw-r--r-- 1 root root  7899997 2012-01-07 libnnz11.so
-rw-r--r-- 1 root root  1863334 01-07 12:50 libocci11.a
lrwxrwxrwx 1 root root       15 01-07 13:33 libocci.so -> libocci.so.11.1
-rwxr-xr-x 1 root root  1260923 01-07 12:50 libocci.so.11.1

編譯OCCI程式時使用如下選項:
OCCI_HOME=/opt/OCCI_11g_R2
OCCI_INCLUDE_DIR=$(OCCI_HOME)/include
OCCI_LIBRARY_PATH=$(OCCI_HOME)/lib
g++ *.cpp  -I$(OCCI_INCLUDE_DIR)  -L$(OCCI_LIBRARY_PATH)  -locci  -lclntsh  -lnnz11     

編譯成功!

注意:編譯時要加上 lnnz11,libclntsh.so 中使用到了 libnnz11.so 中的函式. 否則報如下錯誤

/usr/bin/ld: warning: libnnz11.so, needed by /opt/OCCI_11g_R2/lib/libclntsh.so, not found (try using -rpath or -rpath-link)


(2) 方法二:使用 Oracle Instant Client 11.2.0.1.0 sdk來編譯程式

OCCI_INCLUDE_DIR=/usr/include/oracle/11.2/client64
OCCI_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib

g++ *.cpp -I$(OCCI_INCLUDE_DIR) -L$(OCCI_LIBRARY_PATH) -locci -lclntsh -lnnz11
編譯成功!

(三) 執行OCCI程式

執行OCCI程式必須安裝 ORACLE INSTANT CLIENT,並配置 ORACLE_HOME 環境變數!以上兩種方式安裝的 Oracle  Instant Client 均可以。
export LD_LIBRARY_PATH=/opt/OCCI_11g_R2/lib:$LD_LIBRARY_PATH
./a.out
執行指令碼執行程式,當連線資料庫時,一直報錯誤: Error while trying to retrieve text for error ORA-01804。
弄了半天,最後註釋掉 export LD_LIBRARY_PATH=/opt/OCCI_11g_R2/lib:$LD_LIBRARY_PATH,
即直接使用之前配置的 LD_LIBRARY_PATH 執行程式,問題解決!
所以,這裡是 LD_LIBRARY_PATH  變數的問題。