[C++] 通過OCCI操作Oracle數據庫詳解


  今日趁空,嘗試用C++操作Oracle數據庫。大致步驟列舉如下:

1.安裝OCCI

如果oracle數據庫默認沒有安裝OCCI,可以自己從官網上下載與自己數據庫版本一致的API,地址:http://www.oracle.com/technetwork/topics/linuxsoft-082809.html  ; 其中包含四個軟件包:

oracle-instantclient-sqlplus-10.2.0.5-1.i386.rpm
oracle-instantclient-devel-10.2.0.5-1.i386.rpm
oracle-instantclient-odbc-10.2.0.5-1.i386.rpm
oracle-instantclient-basic-10.2.0.5-1.i386.rpm

安裝完成之后,會在/usr/lib下多個oracle 共享庫文件夾,在/usr/include下多個oracle 頭文件(接口)文件夾(可以將他們放到環境變量中)。我的數據庫版本是10.2.0,下面以此為例。

2.編寫HelloWorld程序測試連接

#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 = "scott";
   string pass = "tiger";
   string srvName = "127.0.0.1:1522/orcl";
   try
   {
      Connection *conn = env->createConnection(name, pass);
      cout<<"conn success"<<endl;
      env->terminateConnection(conn);
   }
   catch(SQLException e)
   {
      cout<<e.what()<<endl;
       return -1;
   }
   Environment::terminateEnvironment(env);
   cout<<"end!"<<endl;
   return 0;
}

編譯命令:

g++ test.cc -o test -I/usr/include/oracle/10.2.0.5/client -L/usr/lib/oracle/10.2.0.5/client/lib -locci -lsqlplus

我沒有將occi的路徑加入到環境變量中,所以此處要顯示列出目錄才能通過編譯,找到共享庫。

運行./test會報錯,libocci.so找不到,解決辦法很簡單:將/usr/lib/oracle/.../lib下的庫加入到LD_LIBRARY_PATH中就可以了。

輸出結果:

success
conn success
end!

注:這件不幸的事情可能只發生在我身上了,本人系統中有三個用戶,其中一個是oracle,而程序是用另一個用戶寫的,於是編譯通過了,但是運行總是報錯:

ORA-12162: TNS:net service name is incorrectly specified

后來查明,這個是由於沒有設置並導出ORACLE_SID。換了oracle用戶試試,居然運行通過了,真的很傷心,原來那個用戶沒有設置Oracle環境變臉怎么能直接本地訪問呢。

3.進行一些操作,執行sql語句

Employees.h

/*
* A simple OCCI test application
* This file contains the Employees class declaration
*/
 
#include <iostream>
#include <occi.h>
#include <iomanip>
 
using namespace oracle::occi;
using namespace std;

class Employees {
public:
   Employees();
   virtual ~Employees();
 
   void List();

private:
   Environment *env;
   Connection  *con;

   string user;
   string passwd;
   string db;
 };
 
 Employees::Employees()
 {
   /*
 69    * connect to the test database as the HR
 70    * sample user and use the EZCONNECT method
 71    * of specifying the connect string. Be sure
 72    * to adjust for your environment! The format
 73    * of the string is host:port/service_name
 74 */
 
   user = "scott";
   passwd = "tiger";
  db = "127.0.0.1:1522/orcl";
 
   env = Environment::createEnvironment(Environment::DEFAULT);
 
   try
   {
     con = env->createConnection(user, passwd, db);
   }
   catch (SQLException& ex)
   {
     cout << ex.getMessage();
 
     exit(EXIT_FAILURE);
   }
}

 Employees::~Employees()
 {
   env->terminateConnection (con);

   Environment::terminateEnvironment (env);
 }
 
 void Employees::List()
{
  /*
104    * simple test method to select data from
105    * the employees table and display the results
106 */
 
   Statement *stmt = NULL;
   ResultSet *rs = NULL;
   string sql = "select EMPNO, ENAME, JOB " \
                "from EMP order by EMPNO";
 
   try
   {
     stmt = con->createStatement(sql);
   }
  catch (SQLException& ex)
  {
     cout << ex.getMessage();
   }
 
   if (stmt)
   {
     try
     {
      stmt->setPrefetchRowCount(32);

      rs = stmt->executeQuery();
    }
    catch (SQLException& ex)
     {
      cout << ex.getMessage();
    }
 
    if (rs)
    {
      cout << endl << setw(8) << left << "EMPNO"
            << setw(22) << left << "ENAME"
           << setw(27) << left << "JOB"
           << endl;
       cout << setw(8) << left << "======"
            << setw(22) << left << "===================="
            << setw(27) << left << "========================="
           << endl;
 
       while (rs->next()) {
        cout << setw(8) << left << rs->getInt(1)
            << setw(22) << left << (rs->isNull(2) ? "n/a" : rs->getString(2))
              << setw(27) << left << rs->getString(3)
              << endl;
      }

       cout << endl;
       stmt->closeResultSet(rs);
     }
     con->terminateStatement(stmt);
   }
 }
 

main.cc

 #include "Employees.h"

 using namespace std;
 using namespace oracle::occi;

 int main (void)
 {
   /*
 48    * create an instance of the Employees class,
 49    * invoke the List member, delete the instance,
 50    * and prompt to continue...
 51 */
 
   Employees *pEmployees = new Employees();
 
   pEmployees->List();

   delete pEmployees;
 
   cout << "ENTER to continue...";
 
   cin.get();
 
   return 0;
 }

 

運行結果就不說了,反正是oracle里自帶的emp表。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM