Oracle presenta unos productos de acceso a bases de datos no-Oracle que básicamente se pueden clasificar en dos grupos: Transparent Gateways y Heterogeneous Services.
Transparent Gateways son módulos de acceso a determinadas bases de datos (SQLServer, Sybase, Teradata, DB2…) Estos módulos están optimizados y ofrecen un mayor rendimiento, por lo que consisten en licencias que se compran por separado.
Por otra parte, los Heterogeneous Services (o Generic Connectivity) están basados en accesos por ODBC/OLEDB y son gratis, aunque el rendimiento es menor.
Ambos persiguen un mismo objetivo: acceder desde Oracle a bases de datos no-Oracle y que sea el propio Oracle el que se encargue de los aspectos de mapeo de tipos, transferencias, etc, etc…
Vamos a ver como podemos hacer para que desde una ventana sqlplus conectada a una instancia Oracle veamos los datos de tablas de una base de datos Teradata con simples ‘SELECTS’. Por supuesto, utilizaremos la segunda solucion (ODBC/OLEDB y GRATIS).
Vamos a ello.
¿Que vamos a necesitar?
Lo primero, que la infraestructura de los Heterogeneous Services (Tablas, ‘packages’, sinónimos, etc…) esté en la base de datos Oracle. Para ello ejecutamos como SYS el ’script’ caths.sql:
SQL*Plus: Release 10.2.0.1.0 - Production on Jue Jun 18 13:22:55 2009 Copyright (c) 1982, 2005, Oracle. All rights reserved. Introduzca el nombre de usuario: sys@XE.localhost as sysdba Introduzca la contraseña: Conectado a: Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production SYS@XE.localhost> @C:\bla\bla\...\10.2.0\server\RDBMS\ADMIN\caths.sql create role hs_admin_role ... Cuerpo del paquete creado. Procedimiento PL/SQL terminado correctamente. Confirmación terminada.
Lo siguiente en configurar es un origen de datos ODBC. Es muy importante que configuremos el origen de datos como DE SISTEMA (no de usuario).
El nuestro se va a llamar TD_HS:


Una vez con el origen de datos ODBC listo comenzamos con la configuración de Oracle:
Para que se entere el ‘listener’ de la conexión debemos informarle. Así en el listener.ora añadiremos una entrada bajo SID_LIST_LISTENER:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = C:\bla\bla\...\server)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\bla\bla\...\server)
(PROGRAM = extproc)
)
(SID_DESC =
(ORACLE_HOME = C:\bla\bla\...\server)
(SID_NAME = TD_HS)
(PROGRAM = hsodbc)
)
)
SID_NAME debe corresponder con nuestro orígen de datos ODBC. PROGRAM es el nombre del módulo de Heterogeneous Services para ODBC (hsodbc.exe)
También necesitaremos una entrada en el tnsnames.ora:
teradata.remote=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)
(HOST = XXX.XXX.XXX.XXX)
(PORT = 1521)
)
(CONNECT_DATA =
(SERVICE_NAME = TD_HS)
(SID = TD_HS)
)
(HS = OK)
)
Como bien de ve en la configuración será el propio ‘listener’ de Oracle el que se encargue de gestionar las conexiones al ODBC.
HS = OK identifica que será un origen Heterogeneous Services. El SID / SERVICE_NAME debe ser una vez más el nombre del origen de datos ODBC. El HOST y el PORT son los del equipo local (donde está Oracle).
Por último, necesitamos un fichero para la configuración de Heterogeneous Services para el origen de datos. Este fichero se llamará init<SID name>.ora y estará en el directorio \hs\admin de la instalación: C:\bla\bla\…\server\hs\admin\initTD_HS.ora
# # HS init parameters # HS_FDS_CONNECT_INFO = TD_HS HS_FDS_TRACE_LEVEL = 1 HS_FDS_TRACE_FILE_NAME = C:\bla\bla\...\server\hs\admin\initTD_HS.trc
Lo importante aquí es la línea HS_FDS_CONNECT_INFO = TD_HS (una vez más el SID). Los otros son para establecer el nivel de las trazas y su fichero.
Si hemos llegado hasta aquí, podemos probar cómo están las cosas con un simple ‘tnsping’:
C:\>tnsping teradata.remote TNS Ping Utility for 32-bit Windows: Version 10.2.0.1.0 - Production on 18-JUN-2009 13:46:53 Copyright (c) 1997, 2005, Oracle. All rights reserved. Archivos de parámetros utilizados: C:\bla\bla\...\server\network\admin\sqlnet.ora Adaptador TNSNAMES utilizado para resolver el alias Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = XXX.XXX.XXX.XXX) (PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = TD_HS) (SID = TD_HS)) (HS = OK)) Realizado correctamente (10 mseg) C:\>
El ‘listener‘ escucha para nuestro TD_HS.
Lo más duro ya está hecho. Ahora sólo nos queda crear un simple dblink en Oracle:
CARLOS@XE.localhost> CREATE DATABASE LINK teradata.remote CONNECT TO carlos IDENTIFIED BY xxxxxxxx USING 'teradata.remote'; Enlace con la base de datos creado.
Si hemos hecho todo bien (y parece que sí), podríamos acceder a la base de datos Teradata con SQL Oracle desde sqlplus:
CARLOS@XE.localhost> SELECT COD_PROVINCIA,
2 DESC_PROVINCIA
3 FROM MY_DB.PROVINCIA@teradata.remote
4 ORDER BY COD_PROVINCIA;
COD_PROVINCIA DESC_PROVINCIA
------------- --------------------
1 Álava
2 Albacete
3 Alicante/Alacant
4 Almería
5 Ávila
6 Badajoz
7 Balears (Illes)
8 Barcelona
9 Burgos
10 Cáceres
11 Cádiz
12 Castellón/Castelló
13 Ciudad Real
14 Córdoba
15 Coruña (A)
16 Cuenca
17 Girona
18 Granada
19 Guadalajara
20 Guipúzcoa
21 Huelva
22 Huesca
23 Jaén
24 León
25 Lleida
26 Rioja (La)
27 Lugo
28 Madrid
29 Málaga
30 Murcia
31 Navarra
32 Ourense
33 Asturias
34 Palencia
35 Palmas (Las)
36 Pontevedra
37 Salamanca
38 Santa Cruz de Tenerife
39 Cantabria
40 Segovia
41 Sevilla
42 Soria
43 Tarragona
44 Teruel
45 Toledo
46 Valencia/València
47 Valladolid
48 Vizcaya
49 Zamora
50 Zaragoza
51 Ceuta
52 Melilla
99 Extranjero
100 Desconocido
54 filas seleccionadas.
Plan de Ejecución
----------------------------------------------------------
Plan hash value: 3717373614
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Inst |IN-OUT|
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2000 | 126K| | 87 (3)| 00:00:02 | | |
| 1 | SORT ORDER BY | | 2000 | 126K| 312K| 87 (3)| 00:00:02 | | |
| 2 | REMOTE | PROVINCIA | 2000 | 126K| | 52 (0)| 00:00:01 | TERAD~ | R->S |
----------------------------------------------------------------------------------------------------------
Remote SQL Information (identified by operation id):
----------------------------------------------------
2 - SELECT "COD_PROVINCIA","DESC_PROVINCIA" FROM "MY_DB"."PROVINCIA" (accessing
'TERADATA.REMOTE' )
Estadísticas
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
1600 bytes sent via SQL*Net to client
413 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
54 rows processed
CARLOS@XE.localhost>
¡Sí señor! Y el autotrace muestra que la ejecución ha sido ‘REMOTE’, como era de esperar.
Y lo que es mejor: podemos utilizar funciones nativas Oracle en el ‘SELECT’ a los datos Teradata:
CARLOS@XE.localhost> SELECT REPLACE(DESC_PROVINCIA,'M','#')
2 FROM MY_DB.PROVINCIA@teradata.remote
3 WHERE COD_PROVINCIA = 28;
REPLACE(DESC_PROVINCIA,'M','#')
---------------------------------------------------------------------------------------------------
#adrid
Plan de Ejecución
----------------------------------------------------------
Plan hash value: 1788691278
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT|
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 1300 | 52 (0)| 00:00:01 | | |
| 1 | REMOTE | PROVINCIA | 20 | 1300 | 52 (0)| 00:00:01 | ALMAC~ | R->S |
--------------------------------------------------------------------------------------------------
Remote SQL Information (identified by operation id):
----------------------------------------------------
1 - SELECT "COD_PROVINCIA","DESC_PROVINCIA" FROM "MY_DB"."PROVINCIA" WHERE
"COD_PROVINCIA"=28 (accessing 'TERADATA.REMOTE' )
Estadísticas
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
456 bytes sent via SQL*Net to client
380 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
CARLOS@XE.localhost>
Y por supuesto, con los ‘GRANTS’ necesarios, no tenemos por qué limitarnos a ‘SELECTS’…
Saludos.
Carlos.
23 Junio 2009 a las 11:23 |
Carlos,
Según la nota 417255.1 del Metalink, Generic Connectivity es una característica desoportada así que a futuro, la opción pasa por Gateways.
23 Junio 2009 a las 11:41 |
Óscar:
¡Cuánto tiempo!
>>”Según la nota 417255.1 del Metalink, Generic Connectivity es una característica desoportada así que a futuro, la opción pasa por Gateways.”
¿Y van a seguir manteniendo los ‘Gateways’ como licencia por separado? ¡Qué morro!
De todas formas, lo mismo siguen manteniendo los ‘Heterogeneous Services’ indocumentados (como ocurre con las conexiones ‘bequeath’, que se pueden seguir utilizando sin problemas y te ahorras el ‘listener’).
Saludos.
Carlos.
25 Junio 2009 a las 13:22 |
>>¿Y van a seguir manteniendo los ‘Gateways’ como licencia por separado? ¡Qué morro!
Hombre, el negocio es el negocio y como ocurre con todas las nuevas funcionalidades poco a poco se persigue rentabilizar la inversión realizada en su desarrollo. Aún así, me reservo mi opinión personal que nunca se sabe quien lee estos blogs