A menudo nos encontramos con organizaciones que tienen ya implantados diferentes entornos para el almacenamiento de la información. Es habitual encontrar una base de datos Oracle para las aplicaciones más importantes con la lógica del negocio, escritas en Oracle Forms y Java, y luego, otras bases de datos (MySQL, Postgres) asociadas a proyectos OpenSource que han decidido usar, porque cubren con total garantía nuevas necesidades que en otro caso serían muy costosas de desarrollar en tiempo y dinero.
En este escenario, suele aparecer la necesidad de vincular información desde el servidor Oracle hacia otras bases de datos como MySQL. Un ejemplo habitual es encontrar la base de datos de nuestros clientes en Oracle, mantenidos desde una aplicación Oracle Forms, y en un momento dado se quiere sincronizar los datos de contacto de estos clientes, con nuestra centralita Asterisk (que usa MySQL) de forma que, cuando la aplicación actualice los datos de algún cliente automáticamente estén disponibles para Asterisk.
Si las dos bases de datos fueran Oracle, podríamos resolverlo mediante un DBLink desde la base de datos de clientes hacia la de Asterisk y desarrollar un pequeño trigger PL/SQL para que cuando se actualicen ciertos datos, automáticamente se actualicen las tablas que lee Asterisk. Al estar este sobre MySQL, no podemos crear un DBLink. Afortunadamente Oracle contempla este escenario a través de Heterogeneus Service (HS) junto a Oracle Database Gateway for ODBC (hs4odbc).
Para configurar este servicio, tendremos que:
- Lo primero será comprobar que instalamos en nuestro servidor Oracle el servicio, chequeando que existe el ejecutable $ORACLE_HOME/bin/dg4odbc
- Lo siguiente será instalar el driver ODBC para MySQL, en nuestro servidor Oracle:
yum install unixODBC.x86_64 mysql-connector-odbc.x86_64
- Ahora, en nuestro servidor MySQL, crearemos un base de datos de prueba, a la que conectar desde Oracle, (cualquiera sabe lo que podría hacernos en MySQL un administrador/desarrollador de Oracle)
mysql> create database oracletest character set latin1;
Es importante usar latin1 para la Base de datos, porque en caso de usar UTF8, tendremos problemas al acceder desde Oracle.
mysql> grant all privileges on oracletest.* to 'oracleconn'@'%'
identified by 'demo' with grant option;
mysql> flush privileges;
mysql> exit; - Ahora, desde el servidor Oracle, probar a conectar al servidor MySQL, usando el cliente MySQL:
mysql -h SERVIDOR_MYSQL --user=oracleconn --password=demo oracletest
... y una vez nos hayamos conectado, crearemos una pequeña tabla:create table demo (
... y aprovecharemos para insertar algún registro...
col1 integer,
col2 date,
col3 varchar(10),
col4 varchar(10) character set utf8,
col5 varbinary(10)) engine innodb;insert into demo(col1, col2, col3, col4, col5)
values(1, cast(now() as date), '0123456789', '0123456789', '0123456789'); - Ahora desde el servidor Oracle, editar el fichero ~oracle/.odbc.ini y configurar el acceso a MySQL vía ODBC, escribiendo el siguiente contenido:
[ODBC Data Sources]
test_mysql = MySQL ODBC Driver 5.1
[test_mysql]
Driver = /usr/lib64/libmyodbc3.so
DATABASE = oracletest
DESCRIPTION = Conexion a MySQL ODBC
PORT = 3306
SERVER = SERVIDOR_MYSQL# UID = oracleconn
# PWD = demo
CHARSET = latin1
TRACEFILE = /tmp/myodbc-demodsn.trc
TRACE = ON - Crear el fichero $ORACLE_HOME/hs/admin/initMysql.ora. El nombre
Mysql
será el SID, y es un nombre arbitrario: Cualquiera que se cree, debe ser $ORACLE_HOME/hs/admin/init$SID.ora#
# HS init parameters
#
HS_FDS_CONNECT_INFO=test_mysql
HS_FDS_TRACE_LEVEL=0
HS_FDS_SHAREABLE_NAME=/usr/lib64/libmyodbc3.so
HS_LANGUAGE=AMERICAN_AMERICA.WE8ISO8859P15
# HS_NLS_NCHAR=AL32UTF8
#
# ODBC specific environment variables
#
set ODBCINI=/home/oracle/.odbc.ini
set LD_LIBRARY_PATH=/usr/lib64:/lib64:/usr/local/lib64:/u01/oracle/soft/product/11.1.0/db_1/lib:/u01/oracle/soft/product/11.1.0/db_1/oracm/lib:/lib:/usr/lib:/usr/local/lib
#
# Environment variables required for the non-Oracle system
#
set HOME=/home/oracle - Añadir a $ORACLE_HOME/network/admin/listener.ora dentro del SID_LIST, el siguiente bloque SID_DESC:
(SID_DESC =
(ORACLE_HOME = /u01/oracle/soft/product/11.1.0/db_1)
(SID_NAME = Mysql)
(PROGRAM = dg4odbc)
(ENVS ="LD_LIBRARY_PATH=/usr/lib64:/lib64:/usr/local/lib64:/u01/oracle/soft/product/11.1.0/db_1/lib:/u01/oracle/soft/product/11.1.0/db_1/oracm/lib:/lib:/usr/lib:/usr/local/lib")
) - Reiniciar el listener de Oracle...
su - oracle
lsnrctl stop
lsnrctl start - Ahora editar el fichero $ORACLE_HOME/network/admin/tnsnames.ora y añadir el siguiente bloque:
DEMOMYSQL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)
(HOST = localhost)
(PORT = 1521)
)
)
(CONNECT_DATA =
(SID = Mysql)
)
(HS = OK)
) - Comprobar que está accesible...
tnsping demoMYSQL
- Crear un DBLINK para acceder a MySQL desde nuestro servidor Oracle...
su - oracle
$ sqlplus / as sysdba;
SQL> CREATE PUBLIC DATABASE LINK dbtestmysql
CONNECT TO oracleconn
IDENTIFIED BY demo
USING 'DEMOMYSQL'; - .. y probar que funciona...
su - oracle
Si estás usando Oracle 11.1.0.6 no te funcionará: Necesitas actualizar tu servidor a 11.1.0.7, porque una de los fallos que arregla tiene que ver con hs4odbc.
$ sqlplus / as sysdba;
SQL> select * from demo@dbtestmysql ;
4 comentarios:
Hola, muy bueno el procedimiento. Lo relicé y me funcionó. Tengo un problema al ejecutar query's parametrizadas, me da un error ORA-02070.
Estoy usando oracle 11.2.0.2 y mysql 5.1.61
Me podés ayudar. Muchas Gracias.
Saludos.
Hola, muy bueno el articulo. Segui tu procedimiento y funciono. ahora estoy teniendo errores cuando ejecuto consultas parametrizadas desde el oracle al mysql. Me podes ayudar?
Desde ya gracias y Saludos.
Diego Ferreira.
Decidme por favor qué consulta lanzais.
Hola, muchas gracias por tu procedimiento, hoy mismo voy a probarlo porque lo explicas mejor que el propio metalink.
Publicar un comentario