• 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("连接数据库出现错误 ");
    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("查询数据出现错误! ");
    23.         system("PAUSE");
    24.         return;
    25.     }
    26.     if (pRst->adoEOF)
    27.     {
    28.         pRst->Close();
    29.         printf("There is no records in this table ");
    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 %s %s %d ", (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("插入数据成功 ");
    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("删除数据成功 ");
    62.     }
    63.     system("PAUSE");
    64.     //pRst->Close();
    65. }

    其中XXX1:是tnsnames.ora中配置的服务名,XXX2是用户名,XXX3是密码。
    DBOperation.h:
     

    点击(此处)折叠或打开

    1. #pragma once
    2. #import "c:program filescommon filessystemadomsado15.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 ");
    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 ");
    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 ");
    77.     printf("ErrorNo: %d Error Message:%s Error Source:%s Error Description:%s ", 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)ociinclude
    3.添加头文件目录
        $(ORACLE_HOME)ocilib
    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++连接方式待续。。。。
  • 相关阅读:
    MyBatis整合Spring编码
    Intellij IDEA中如何给main方法赋args
    InputStream类的available()方法
    使用IDEA在引入Schema空间时报错URI is not registered解决方法以及Idea @Autowired取消提示 方法
    HelloServlet类继承HttpServlet利用HttpServletResponse对象
    DAO层单元测试编码和问题排查
    安卓Activity布局简述
    新建工程spring boot
    MySQL无法启动
    CoffeeScript编写简单新闻页(仅UI)
  • 原文地址:https://www.cnblogs.com/aabbcc/p/5964366.html
Copyright © 2020-2023  润新知