C++操作oracle數據庫


數據庫操作方式:可以采用ADO方式,也可以采用oracle本身提供的Proc*C/C++或者是OCCI方式操作數據庫。
 
 連接方式:可以是客戶端連接、也可以是服務器端連接。
 
 數據庫配置:無論是何種連接都需要進行數據庫連接的配置,一般在ORACLE_HOME下面的network/admin/tnsnames.ora文件中進行配置,如果沒有此目錄或者是此文件,需要自己手工添加。內容格式大致如下:

點擊(此處)折疊或打開

  1. BM2D0 =
  2.   (DESCRIPTION =
  3.     (ADDRESS_LIST =
  4.       (ADDRESS = (PROTOCOL = TCP)(HOST = XXX.XXX.XXX.XXX)(PORT = 1521))
  5.     )
  6.     (CONNECT_DATA =
  7.       (SERVICE_NAME = BM2D0)
  8.     )
  9.   )
其中 橄欖色可任意起名,一般在數據庫連接是作為服務和用戶名、密碼一起確定數據庫連接的參數。
    第一個鮮粉色是遠程oracle數據庫所在服務器的IP地址,端口號一般為1521。
    第二個鮮粉色是遠程oracle所在主機的全局數據庫名字,不能隨意更改。
    后兩個搭配起來能夠確定唯一連接對象。
客戶端連接:
方式一:ADO
main.cpp

點擊(此處)折疊或打開

  1. #include "DBOperation.h"
  2. #include <iostream>
  3. using namespace std;
  4. void main()
  5. {
  6.     CDBOperation dbOper;
  7.     bool bConn = dbOper.ConnToDB("Provider=OraOLEDB.Oracle.1;Persist Security Info=True;Data Source=xxx1", "xxx2", "xxx3");
  8.     if (false == bConn)
  9.     {
  10.         printf("連接數據庫出現錯誤\n");
  11.         system("PAUSE");
  12.         return;
  13.     }
  14.     _RecordsetPtr pRst;
  15.     //執行查詢語句
  16.     //char *sql = "select * from TSTUDENT";
  17.     char sql[255] = {0};
  18.     strcpy(sql, "select * from TSTUDENT");
  19.     pRst = dbOper.ExecuteWithResSQL(sql);
  20.     if (NULL == pRst)
  21.     {
  22.         printf("查詢數據出現錯誤!\n");
  23.         system("PAUSE");
  24.         return;
  25.     }
  26.     if (pRst->adoEOF)
  27.     {
  28.         pRst->Close();
  29.         printf("There is no records in this table\n");
  30.         return;
  31.     }
  32.     _variant_t vSno, vName, v***, vAge, vDno, vDname, vCname;
  33.     while (!pRst->adoEOF)
  34.     {
  35.         //pRst->MoveFirst(); //記錄集指針移動到查詢結果集的前面
  36.         vSno = pRst->GetCollect(_variant_t((long)0));
  37.         vName = pRst->GetCollect(_variant_t("name"));
  38.         v*** = pRst->GetCollect(_variant_t("***"));
  39.         vAge = pRst->GetCollect(_variant_t("age"));
  40.         //vDno = pRst->GetCollect("dno");
  41.         //vDname = pRst->GetCollect("dname");
  42.         //vCname = pRst->GetCollect("cname");
  43.         printf("%s\t%s\t%s\t%d\n", (LPSTR)(LPCSTR)(_bstr_t)vSno, (LPSTR)(LPCSTR)_bstr_t(vName), (LPSTR)(LPCSTR)_bstr_t(v***), vAge.intVal);
  44.         pRst->MoveNext();
  45.     }
  46.     
  47.     //執行插入語句
  48.     //sprintf(sql, "insert into TSTUDENT(sno, name, ***, age) values('%s', '%s', '%s', %d)", "20080016", "全局", "女", 25);
  49.     strcpy(sql, "insert into TSTUDENT(sno, name, ***, age) values('20080001', '全局', '女', 25)");
  50.     pRst = dbOper.ExecuteWithResSQL(sql);
  51.     if (NULL != pRst)
  52.     {
  53.         printf("插入數據成功\n");
  54.     }
  55.     //執行刪除語句
  56.     
  57.     sprintf(sql, "delete from TSTUDENT where sno = '%s'", "20080017");
  58.     pRst = dbOper.ExecuteWithResSQL(sql);
  59.     if (NULL != pRst)
  60.     {
  61.         printf("刪除數據成功\n");
  62.     }
  63.     system("PAUSE");
  64.     //pRst->Close();
  65. }

其中XXX1:是tnsnames.ora中配置的服務名,XXX2是用戶名,XXX3是密碼。
DBOperation.h:
 

點擊(此處)折疊或打開

  1. #pragma once
  2. #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
  3. class CDBOperation
  4. {
  5. public:
  6.     //初始化數據庫操作需要的對象
  7.     CDBOperation(void);
  8.     ~CDBOperation(void);
  9.     //連接至數據庫
  10.     bool ConnToDB(char *ConnectionString, char *UserID, char *Password);
  11.     //數據庫操作函數
  12.     //查詢操作 刪除以及添加
  13.     _RecordsetPtr ExecuteWithResSQL(const char *);
  14.     //bool ExecuteNoResSQL(const char *);//delete and add
  15. private:
  16.     void PrintErrorInfo(_com_error &);
  17. private:
  18.     //初始化數據庫連接、命令、記錄集
  19.     _ConnectionPtr CreateConnPtr();
  20.     _CommandPtr CreateCommPtr();
  21.     _RecordsetPtr CreateRecsetPtr();
  22. private:
  23.     //數據庫連接需要的連接、命令操作對象
  24.     _ConnectionPtr m_pConnection;
  25.     _CommandPtr m_pCommand;
  26. };

DBOperation.cpp

點擊(此處)折疊或打開

  1. #include "DBOperation.h"
  2. CDBOperation::CDBOperation(void)
  3. {
  4.     CoInitialize(NULL);
  5.     m_pConnection = CreateConnPtr();
  6.     m_pCommand = CreateCommPtr();
  7. }
  8. CDBOperation::~CDBOperation(void)
  9. {
  10.     //m_pCommand->Close();
  11.     m_pConnection->Close();
  12. }
  13. bool CDBOperation::ConnToDB(char *ConnectionString, char *UserID, char *Password)
  14. {
  15.     if (NULL == m_pConnection)
  16.     {
  17.         printf("Failed to create connection\n");
  18.         return false;
  19.     }
  20.     try
  21.     {
  22.         HRESULT hr = m_pConnection->Open(ConnectionString, UserID, Password, NULL);
  23.         if (TRUE == FAILED(hr))
  24.         {
  25.             return false;
  26.         }
  27.         m_pCommand->ActiveConnection = m_pConnection;
  28.         return true;
  29.     }
  30.     catch(_com_error &e)
  31.     {
  32.         PrintErrorInfo(e);
  33.         return false;
  34.     }
  35. }
  36. _RecordsetPtr CDBOperation::ExecuteWithResSQL(const char *sql)
  37. {
  38.     //已經在連接至數據庫的時候進行判斷了
  39.     //if (NULL == m_pCommand || 0 == m_pConnection->State)
  40.     //{
  41.     //    printf("Failed to create command OR the state of connection is zero\n");
  42.     //    return NULL;
  43.     //}
  44.     //char *query = new char;
  45.     //strcpy(query, sql);
  46.     try
  47.     {
  48.         m_pCommand->CommandText = _bstr_t(sql);
  49.         _RecordsetPtr pRst = m_pCommand->Execute(NULL, NULL, adCmdText);
  50.         return pRst;
  51.         //_variant_t ra;
  52.         //_RecordsetPtr pRst = m_pConnection->Execute((_bstr_t)query, &ra, adCmdText);
  53.     }
  54.     catch(_com_error &e)
  55.     {
  56.         PrintErrorInfo(e);
  57.         return NULL;
  58.     }
  59. }
  60. //bool CDBOperation::ExecuteNoResSQL(const char *sql)
  61. //{
  62. //    //if (NULL == m_pCommand || 0 == m_pConnection->State)
  63. //    //{
  64. //    //    printf();
  65. //    //}
  66. //    try
  67. //    {
  68. //        char *query = NULL;
  69. //        strcpy(query, sql);
  70. //        m_pCommand->CommandText = (_bstr_t)query;
  71. //
  72. //    }
  73. //}
  74. void CDBOperation::PrintErrorInfo(_com_error &e)
  75. {
  76.     printf("Error infomation are as follows\n");
  77.     printf("ErrorNo: %d\nError Message:%s\nError Source:%s\nError Description:%s\n", e.Error(), e.ErrorMessage(), (LPCTSTR)e.Source(), (LPCTSTR)e.Description());
  78. }
  79. _ConnectionPtr CDBOperation::CreateConnPtr()
  80. {
  81.     HRESULT hr;
  82.     _ConnectionPtr connPtr;
  83.     hr = connPtr.CreateInstance(__uuidof(Connection));
  84.     if (FAILED(hr) == TRUE)
  85.     {
  86.         return NULL;
  87.     }
  88.     return connPtr;
  89. }
  90. _CommandPtr CDBOperation::CreateCommPtr()
  91. {
  92.     HRESULT hr;
  93.     _CommandPtr commPtr;
  94.     hr = commPtr.CreateInstance(__uuidof(Command));
  95.     if (FAILED(hr) == TRUE)
  96.     {
  97.         return NULL;
  98.     }
  99.     return commPtr;
  100. }
  101. _RecordsetPtr CDBOperation::CreateRecsetPtr()
  102. {
  103.     HRESULT hr;
  104.     _RecordsetPtr recsetPtr;
  105.     hr = recsetPtr.CreateInstance(__uuidof(    Command));
  106.     if (FAILED(hr) ==TRUE)
  107.     {
  108.         return NULL;
  109.     }
  110.     return recsetPtr;
  111. }

方式二:OCCI
默認oracle安裝了occi庫,但是只是安裝了release版本的資源,因此需要將程序配置為release模式,或者是參看http://www.189works.com/article-42057-1.html為debug模式獲取必備的頭文件以及庫文件,本文采用的是release模式,使用默認安裝的庫文件以及頭文件。
1.修改配置屬性
    改為Rlease模式
2.添加庫文件目錄
    $(ORACLE_HOME)\oci\include
3.添加頭文件目錄
    $(ORACLE_HOME)\oci\lib
4.添加庫文件:oraocci10.lib
應用程序:

點擊(此處)折疊或打開

  1. //代碼的目的就是驗證makefile中oracle的頭文件和lib文件路徑是否正確了
  2. #include <iostream>
  3. #define WIN32COMMON //避免函數重定義錯誤
  4. #include <occi.h>
  5. using namespace std;
  6. using namespace oracle::occi;
  7. int main()
  8. {
  9.   Environment *env=Environment::createEnvironment();
  10.   cout<<"success"<<endl;
  11.   string name = "xxx";
  12.   string pass = "xxx";
  13.   string srvName = "xxx";
  14.   try
  15.   {
  16.     Connection *conn = env->createConnection("bsm3", "bsm3", "BSM3");
  17.     cout<<"conn success"<<endl;
  18.     env->terminateConnection(conn);
  19.   }
  20.   catch(SQLException e)
  21.   {
  22.     cout<<e.what()<<endl;
  23.     system("pause");
  24.     return -1;
  25.   }
  26.   Environment::terminateEnvironment(env);
  27.   cout<<"end!"<<endl;
  28.   system("pause");
  29.   return 0;
  30. }

服務器端:AIX服務器
方式一:OCCI
helloworld.cpp

點擊(此處)折疊或打開

  1. //代碼的目的就是驗證makefile中oracle的頭文件和lib文件路徑是否正確了
  2. #include <iostream>
  3. #include <occi.h>
  4. using namespace std;
  5. using namespace oracle::occi;
  6. main()
  7. {
  8.   Environment *env=Environment::createEnvironment();
  9.   cout<<"success"<<endl;
  10.   string name = "xxx";
  11.   string pass = "xxx";
  12.   string srvName = "xxx";
  13.   try
  14.   {
  15.     Connection *conn = env->createConnection(name, pass, srvName);
  16.     cout<<"conn success"<<endl;
  17.     env->terminateConnection(conn);
  18.   }
  19.   catch(SQLException e)
  20.   {
  21.     cout<<e.what()<<endl;
  22.   }
  23.   Environment::terminateEnvironment(env);
  24.   cout<<"end!"<<endl;
  25. }

Makefile:

點擊(此處)折疊或打開

  1. ###########################################
  2. #Makefile for the OCCI demo programs
  3. ###########################################
  4. INC=-I${ORACLE_HOME}/precomp/public -I${ORACLE_HOME}/rdbms/public
  5. LIB=-L${ORACLE_HOME}/lib -locci #-bnoquiet #-bloadmap
  6. FLAGS=-q64 -g
  7. #為方便取下面三個變量,目標為helloworld,源文件是helloworld.cpp,編譯后文件helloworld.o
  8. PRG=helloworld
  9. SRC=helloworld.cpp
  10. OBJ=helloworld.o
  11. #下面是常規的makefile內容,$@表示依次取目標執行,這里只有helloworld一個目標。實際等價於
  12. #CC -o helloworld helloworld.o 不過加入了include和lib文件。而helloworld.o需要后續完成
  13. $(PRG):$(OBJ)
  14.         @echo "begin link......"
  15.         ${CC} ${FLAGS} ${INC} ${LIB} -o $@ $(OBJ)
  16. #helloworld目標依賴helloworld.o生成,所以該句就是編譯.c生成.o文件。只不過加入了include和lib文件
  17. $(OBJ):$(SRC)
  18.         @echo "begin compile......"
  19.         ${CC} ${FLAGS} ${INC} ${LIB} -c $(SRC)
  20. #后面的內容不是make的內容了,而是make clean內容。比如想重新make之前,清除.o等文件,執行make clean語句
  21. #.PRNOY語句表明 clean關鍵詞是個偽目標。make不自動執行。
  22. .PRONY:clean
  23. clean:
  24.         @echo "Removing linked and compiled files....."
  25.         rm -f $(OBJ) $(PRG)
關於客戶端以及服務器端采用PROC*C/C++連接方式待續。。。。


免責聲明!

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



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