Heterogeneous Services: SQL a Teradata desde Oracle.

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:

TD_DS_1

TD_DS_2

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.

3 comentarios para “Heterogeneous Services: SQL a Teradata desde Oracle.”

  1. Óscar de la Torre Dice:

    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.

    • carlosal Dice:

      Ó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.

      • Óscar de la Torre Dice:

        >>¿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 :)

Escribe un comentario