Windows下Oracle10g异构连接MySQL5

来源:互联网 发布:数据采集协议 编辑:程序博客网 时间:2024/06/07 02:27

   最近看到一篇oracle连接mysql的文章,自己很好奇也尝试了一下,遇到一些问题并解决掉,在这里记录一下。我的环境:OS:windows server 2003、oracle10.2.0和MySql5在同一台主机上。

一、配置mysql

1、创建数据库和表

mysql>create database mysqltest;
mysql>use mysqltest
mysql>create table ttt(
mysql>tid INTEGER,
mysql>tname VARCHAR(20));
mysql>insert into ttt values(1,'111');
mysql>select * from ttt;

2、配置odbc数据源

 开始->管理工具->数据源(ODBC)->ODBC数据源管理器->系统DNS->添加->选择数据驱动程序:MySQL ODBC 5.1 Driver

(注意:如果没有安装过mysql的odbc驱动需要先下载odbc驱动安装,本人是在http://download.csdn.net/source/2463889下载的。)

选择驱动程序以后点击“完成”,然后配置odbc数据源信息:

 

配置好以后点击“Test”测试odbc连接mysql是否成功,如果成功才能进行下一步,点击“ok”完成配置。

注意:这里要在“系统DSN ”里添加配置,如果在“用户DSN”里配置会找不到odbc源,错误信息如下:

 

二、配置oracle

1、配置HS

在%ORACLE_HOME%/hs/admin/ 路径下添加initmysqltest.ora 里面有两条记录

#这里指定odbc的名称
HS_FDS_CONNECT_INFO = mysql
#指定追逐级别,一般设成OFF,为了方便调试这里设成debug,在%ORACLE_HOME%/hs/trace下查看追逐文件信息
HS_FDS_TRACE_LEVEL = debug

 

2、配置监听listener.ora

文件路径:%ORACLE_HOME%/NETWORK/ADMIN/

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (PROGRAM =hsodbc--这里必须是hsodbc,表明采用hsodbc异构连接
      (ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
      (SID_NAME=mysqltest) --这里指定mysql数据库实例名称
    )

  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = cuihaiyang)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
  )

配置完成重新启动监听。

3、配置tnsnames.ora

文件路径:%ORACLE_HOME%/NETWORK/ADMIN/  ,新增一条记录

MYSQLTEST =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = mysqltest) --这里指定mysql数据库实例名称
    )
    (HS=OK)
  )

 

4、创建数据库链路并测试

SQL> create database link mysql connect to "root" identified by "123" using 'mys
qltest'
;--注意使用单引号

数据库链接已创建。

SQL> select * from ttt@mysql;

       tid
----------
         1

SQL> select count(*) from ttt@mysql;

  COUNT(*)
----------
        49

 

可见已经可以从mysql中查询出数据。

PS:仔细观察结果发现存在两个问题

1、在mysql下创建表ttt有两个字段tid和tname现在却只查出了一个;

2、只有一条记录,但是count(*)查出来的是49。

SQL> delete from ttt@mysql;
 
1 row deleted
 
SQL> select count(*) from ttt@mysql;
 
            COUNT(*)
--------------------
                  48

对于疑问1:查找了很多资料得出的结论是HSODBC的问题,查看HSODBC的跟踪文件发现存在一句“DB_ODBC_RECORD (1217): ; Skipped field tname, unrecognized datatype.”,说明HSODBC不能识别tname字段的类型,但是tname字段是varchar类型的,oracle中也支持varchar类型,很疑惑为什么不能识别。继续查找发现了一篇帖子:http://forums.oracle.com/forums/thread.jspa?threadID=2172072,楼主也遇到了HS没有返回所有字段的情况,仔细看了跟帖发现是odbc从mysql读取数据后转换成了odbc的数据类型,其中varchar被转换成了SQL_WVARCHAR,而hsodbc不能识别SQL_WVARCHAR,所以才造成了在oracle中不能返回所有字段的情况,HSODBC从2008年开始已经不再支持了,oracle11g中也使用DG4ODBC代替HSODBC,看来要解决这个问题还是需要使用DG4ODBC,干脆换成11g得了。

对于疑问2:在HSODBC的跟踪文件发现“hoastmt.c (304): ; Array fetch size is: 1.”,说明返回的结果是1条,在odbc的isql工具中执行“SELECT COUNT(*) FROM mysqltest.ttt” 返回结果也是1,后来尝试在oracle中执行select count("id") 结果正常了,分析半天日志也没找出什么原因,不过现在能得到正确的记录数量了,暂且到此。

关于oracle HS的深入解析可以参考:http://www.cnblogs.com/wwwiori/archive/2009/06/22/1508068.html