VC++.net使用OCCI连接远程Oracle数据库

       由于项目的需要,需要用C++去连Oracle数据库,Oracle版本为10g,在经过n次错误后终于成功连接。
        最开始用ADO连,装上客户端以后,在Oracle Net Manager中设置服务命名,测试连接成功,然后
设置ODBC数据源,测试也成功,ADO连接串写上"DSN=xxx"就能连上了,但是在释放连接时总是出错,
经过多次尝试后放弃,在网上看到Oracle专门为C++提供了连接的接口OCCI,于是尝试采用这种方法。
        一、安装Oracle客户端
                安装方式选择为管理员。安装完以后设置服务命名。在%ORACLIENTHOME%/NETWORK/ADMIN目录下tnsnames.ora文件记录了服务命名的设置。我的设置如下:
               
  ORCL_192.168.0.3 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.3)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = orcl)
      (SERVER = DEDICATED)
    )
  )

ORCL =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.3)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = ORCL_192.168.0.3)
    )
  )
 

其中192.168.0.3为远程Oracle服务器IP地址
设置完以后在Net Manager中测试连接,成功就OK了。
        二、设置VC++.net环境
        我用的编译器是VS2003,首先在工具---选项中Project添加包含文件%OracleClientHome%/Oci/include
添加库文件%OracleClientHome%/Oci/lib/msvc/vc71和%OracleClientHome%/Oci/lib/msvc如果是VC6.0的话就
添加%OracleClientHome%/Oci/lib/msvc/vc6。
然后设置项目属性,在编译器---链接中添加lib文件,oraocci10d.lib,之后把oraocci10d.dll文件复制到system32目录下,这个文件在VC71目录下。
第三步在C++----代码生成中设置运行时库为多线程DLL或是多线程调试DLL,注意这一步设置很重要,
没有设置的话会造成getString函数出错。
        三、代码
       

 #include  " stdafx.h "
#include 
< occi.h > 
using   namespace  std;
 using   namespace
 oracle::occi ;
 int
 main() 
 
{
    Environment
*  env = Environment::createEnvironment( " ZHS16GBK " " UTF8 "
);
    
// Environment *env=Environment::createEnvironment(Environment::DEFAULT); 

 

    
string  mc;
    
 
{
        Connection 
* conn  =  env -> createConnection( " system " " system " " orcl_192.168.0.3 "
);
        
        
try 

          
{
            Statement 
* stmt  =  conn -> createStatement( " select * from test1 "
);

            ResultSet 
* rs  =  stmt ->
executeQuery();
            
while (rs -> next()  ==   true
)
            
 
{
                mc
= rs -> getString( 1
);
                cout 
<<  mc  <<
 endl;
            } 

            stmt
-> closeResultSet(rs);
            conn
->
terminateStatement(stmt);
        } 

        
catch  (SQLException e)
        
 
{
            cout
<<
e.what();
        } 

        env
-> terminateConnection(conn);
    } 

    Environment::terminateEnvironment(env);
    system(
" pause " );
    
return   0
;
}

orcl_192.168.0.3就是前面设置的连接串。
测试成功。以上就是所有的设置过程,唉,还是jdbc好连阿。。。

注意,项目属性中运行时库一定要设置为多线程DLL或是多线程调试DLL,否则getString函数就会出错,我在这个问题上也卡了很长时间,单步调试发现是在string对象析购时出错,在网上看到一篇文章得到答案。
        原因是由于程序中使用的内存管理多来源于crt提供的例程,而非直接使用操作系统的接口,这些例程都需要维护一些module全局数据(例如维护池、维护空闲块、或者标记已申请的块等等,不同的实现中有不同的作用),当他们被静态连编时,实际上这些“全局数据”就不“全局”了,不同的module各自为政,每份module都有自己的“全局数据”,自身的内存信息不为他人所知,module A的合法内存快自然不可能通得过module B的合法性验证

解决问题的方法有:
1、不要跨module传递c++对象,或者避免释放跨module申请的内存

2、将参与合作的module统统以multithreaded dll方式链入crt库,让他们的“全局”数据真正全局,注意,所有有交互的module都需要动态链入crt。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值