Você está na página 1de 17

Oracle Heterogeneous Services (HS)

O HS, como é conhecido, é um componente integrado ao Bando de dados Oracle, que

provê acesso a outros bancos de dados de terceiros.

Para que isso funcione, você precisa usar ainda um agente complementar ao serviço, que tanto pode ser um Transparent Gateway, que é construído especificamente para a tecnologia do banco de dados que você quer acessar, ou um agente genérico, como por exemplo, uma conexão ODBC.

Nós seguiremos neste documento com a segunda opção.

Ambiente utilizado:

- Windows 10 Enterprise Edition;

- Oracle Database 11g R2 XE;

- MS SQL Server Express 2016 com SP1;

- Apex 5.1;

O objetivo, neste caso, é acessar e manipular os dados em uma base de dados SQL

Server, de modo totalmente transparente para um aplicativo Apex, rodando naturalmente, em uma base de dados Oracle.

Em teoria, a configuração deveria ser simples. E observando os passos necessários e os arquivos envolvidos, depois de tudo pronto, realmente é bastante simples. O problema é que não é tão simples assim chegar a estes arquivos finais de configuração, da maneira correta. Existem muitos posts a respeito e tutoriais completos na web, mas quase todos tratam do assunto usando versões mais antigas, Linux ou outros bancos de dados. Então, encontrar o caminho que funcione com a sua configuração específica, não é tão simples quanto parece, e acaba se tornando um jogo de tentativa e erro, até que se chegue ao resultado desejado.

Felizmente, temos algumas ferramentas da própria Oracle, que nos ajudam a testar partes da configuração, antes de prosseguir para o passo seguinte, e nós mesmos, podemos garantir condições mínimas em que podemos confiar, com outras ferramentas, para que possamos eliminar logo cedo, dúvidas quanto ao funcionamento de um ou outro componente envolvido no processo.

Dito isso, vamos começar a seguir os passos necessários para termos a conexão funcionando e disponível em nosso ambiente Apex.

O primeiro ponto a notar, é que usei no meu ambiente o SQL Server Express. Esta versão

tem uma particularidade. A de não ter uma porta fixa para comunicação via TCP (rede). Aqui, enfrentei o primeiro problema. Lendo a documentação e outras fontes da web, você vai descobrir que existe uma forma de fazer com que ele use uma porta fixa, através de configurações. A informação é que ele não traz por DEFAULT uma porta fixa configurada, mas que isso pode ser feito.

Pois bem. Acessei as telas mostradas abaixo, no SQL Server Configuration Manager, me certifiquei de que os protocolos de rede do Express estavam funcionando, e configurei a porta fixa, conforme dito na documentação. Aqui um ponto importante. Caso o serviço TCP/IP esteja desabilitado, você precisa habilitar, e reiniciar os serviços do SQL Server Express antes de prosseguir.

Depois da configuração feita, criei uma conexão a partir de outra máquina da rede, com o SQL Developer, da Oracle, e um drive java, comprovadamente funcional e muito elogiado. Queria ter certeza de que o SQL Express estava funcionando na rede, antes de prosseguir, pois caso não conseguisse conectar depois de configurar o HR, poderia pelo menos ter certeza de que não era nem um problema de rede, nem de porta do SQL Server Express.

Na primeira tentativa de conexão, não funcionou. Na segunda também não e nenhuma mais daí em diante, de forma nenhuma. Revisei várias e várias vezes a conexão, número de porta, protocolos, e nada. Na máquina local funcionava bem, por usar o agente do próprio banco, e não uma porta. Para encurtar, o problema era justamente a porta configurada. Não sei o motivo, e francamente, não procurei saber. Não sei se é um bug, ou se existe ainda alguma configuração adicional necessária, mas mesmo seguindo as indicações de posts e documentação, a porta indicada não funciona.

Você verá nas imagens abaixo. A documentação diz que devemos:

- Acessar o protocolo TCP/IP dos serviços de rede do SQL Server;

- Encontrar o endereço que nos interessa disponibilizar. No meu caso, é o 10.0.1.7, ip do meu servidor interno;

- Você deve mudar o valor da propriedade “TCP Dynamic Ports”, e deixar vazio. Nem mesmo com zero. Limpar o campo;

- Na propriedade “TCP Port”, informar a porta que você quer disponibilizar. Neste caso, 1433;

Simplesmente não funciona. Eu consegui resolver e acessar via rede, através da porta indicada em outro ponto da configuração, mais abaixo, na mesma lista de endereços. Existe no final desta lista um endereço chamado “IPAll”, que traz um outro número de porta dinâmica. Com este número, consegui acessar via rede, sem problemas.

Segue a sequencia de imagens:

número de porta dinâmica. Com este número, consegui acessar via rede, sem problemas. Segue a sequencia
Protocolos de rede e a porta modificada no endereço “10.0.1.7”.

Protocolos de rede e a porta modificada no endereço “10.0.1.7”.

Aqui, a porta que funcionou, no “IPAll”. Eu poderia ter feito outros testes, mas como

Aqui, a porta que funcionou, no “IPAll”.

Eu poderia ter feito outros testes, mas como não é meu objetivo principal, e teoricamente, na versão “Full" do SQL Server este problema não deve existir, então, segui em frente.

O objetivo principal neste caso, será acessar uma tabela existente, no SQL Server, e manipular seus dados, através de um Database link, criado no ambiente Apex, no Banco Oracle, como se fosse uma tabela local.

Abaixo, veremos a tabela criada para testes e alguns dados existentes na mesma.

criada para testes e alguns dados existentes na mesma. O banco de dados que iremos acessar,

O banco de dados que iremos acessar, tem o incrivelmente criativo nome de “Teste”, uma tabela

chamada “Estados”, que possui 5 registros.

O próximo passo é criar uma fonte de dados ODBC, de 64 bits.

Neste ponto, é preciso muita atenção em dois detalhes importantes:

-

A fonte de dados deve ser um DSN de sistema, e não de usuário.

-

O nome da fonte de dados deve ser escolhido com cuidado. Ele será usado nos arquivos de configuração do HR, e deve ser escrito exatamente da mesma forma nestes arquivos. Então, se possível, escolha um nome curto, fácil de lembrar, significativo em relação a origem dos dados, e totalmente em letras minúsculas ou maiúsculas. Evite problemas ao misturar letras que podem ser difíceis de lembrar mais adiante.

O

Wizard do Windows que cria este DSN é muito prático e intuitivo, mas existem opções que você

precisa escolher de determinada forma, ou mesmo decidir entrar em determinada tela, para garantir que a configuração será feita da maneira necessária. Entre as configurações, temos:

- Na segunda tela do Wizard, após a escolha do nome da fonte de dados, escolher a forma de autenticação do próprio SQL Server, e não a do Windows. Ou seja, usaremos o usuário sa padrão, e a senha determinada para ele no momento da instalação;

- Logo abaixo do botão de rádio de escolha da forma de autenticação, temos um outro botão, chamado “Configuração do Cliente”. Precisamos clicar neste botão, para podermos fazer escolhas diferentes do padrão na tela que se abrirá em seguida;

- Normalmente, a opção que vem marcada por default nesta tela é “Pipes Nomeados”. Você deve escolher “TCP/IP”;

- Por mais estranho que pareça, deixe marcada a opção “Determinar porta dinâmicamente”, a direita desta tela. Lembre-se, que neste caso, nós iremos nos conectar com a fonte de dados, através de um nome, e não de uma porta. Então, é melhor deixar o próprio sistema usar a porta que ele considerar adequada. O caso que relatei, no início deste texto, era para conectar através de outro software, e não do HR da Oracle;

- Nas próximas telas, a única coisa que alterei, foi o banco de dados padrão, que já deixei como “Teste”;

Segue a sequência de telas:

já deixei como “Teste”; Segue a sequência de telas: ODBC de 64 Bits. Fonte de dados

ODBC de 64 Bits. Fonte de dados do Sistema, e não do Usuário.

Nome simples, todo em letras minúsculas.

Nome simples, todo em letras minúsculas.

Forma de autenticação, e acesso a configuração do cliente. Configuração do cliente, como TCP/IP e

Forma de autenticação, e acesso a configuração do cliente.

Forma de autenticação, e acesso a configuração do cliente. Configuração do cliente, como TCP/IP e porta

Configuração do cliente, como TCP/IP e porta dinâminca.

Definição do banco de dados default.

Definição do banco de dados default.

Conclusão da criação e configuração do DSN de Sistema. Deste ponto em diante, o que

Conclusão da criação e configuração do DSN de Sistema.

Deste ponto em diante, o que precisamos fazer exige um editor de texto simples, de sua escolha, e o uso do prompt de comando do Windows, em modo administrador. Em modo simples, teremos problemas.

Para configurar o HR e fazer com que acesse a fonte de dados ODBC que acabamos de criar, precisamos trabalhar com basicamente 3 arquivos, em locais diferentes, reiniciar um serviço da Oracle e iniciar outro. E isso é tudo. Mas temos pegadinhas…

Para facilitar nossa vida, a Oracle disponibiliza junto com a instalação, alguns arquivos de exemplo, com a extensão .sample acrescentada, deixando clara a sua função.

O primeiro local que precisamos acessar, é:

C:\oraclexe\app\oracle\product\11.2.0\server\hs\admin

Nesta pasta, temos os arquivos .sample necessários que nos servirão de base, e um arquivo que servirá para inicializar o serviço, ou melhor, o listener que criaremos.

Os arquivos modificados, não ficarão nesta pasta, com exceção de um, que é o inicializador do listener. Os outros dois arquivos, devem ser movidos, depois de alterados, para a seguinte pasta, que realmente é levada em conta na configuração dos serviços Oracle:

C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN

Vamos então a primeira pasta: C:\oraclexe\app\oracle\product\11.2.0\server\hs\ADMIN

Nesta pasta, temos os vários arquivos de exemplo, e um em especial, que deve ser renomeado, e permanecerá nesta mesma pasta. É o arquivo initdg4odbc.ora.sample, que deve ser renomeado para init<nomedodsn>.ora, além de editado. No nosso exemplo, ele passará a se chamar “initmssconn.ora”, e seu conteúdo interno ficará assim:

#

This is a sample agent init file that contains the HS parameters that are

#

needed for the Database Gateway for ODBC

#

#

HS init parameters

#

HS_FDS_CONNECT_INFO = mssconn HS_FDS_TRACE_LEVEL = OFF

#

#

Environment variables required for the non-Oracle system

#

#set <envvar>=<value>

As linhas que mudam são:

HS_FDS_CONNECT_INFO = mssconn …Onde mssconn é o nome do nosso DSN recém criado.

HS_FDS_TRACE_LEVEL = OFF …E aqui deve estar como OFF. Seja lá o valor que tiver no arquivo de exemplo, mude para OFF.

O próximo arquivo que vamos alterar, é o listener.ora.sample. copie para listener.ora apenas, para preservar o arquivo de exemplo. O conteúdo dele deve ficar assim:

SID_LIST_LISTENER_MSSCONN = (SID_LIST = (SID_DESC = (SID_NAME = mssconn) (ORACLE_HOME = C:\oraclexe\app\oracle\product\11.2.0\server) (PROGRAM = dg4odbc)

)

)

LISTENER_MSSCONN = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = PNPKEY)) (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6QTHL5D)(PORT = 1522))

)

As linhas importantes aqui são:

SID_LIST_LISTENER_MSSCONN =

Aqui começa a descrição do novo listener. Note que é uma agregação de identificadores. Sendo assim, o nosso novo listener vai se chamar LISTENER_MSSCONN. Mas abaixo, vamos utilizar este nome…

Ainda no mesmo bloco, temos as linhas:

(SID_NAME = mssconn) (ORACLE_HOME = C:\oraclexe\app\oracle\product\11.2.0\server) (PROGRAM = dg4odbc)

Onde:

SID_NAME é o nome de nosso DSN novamente. E deve ser escrito exatamente da mesma forma.

ORACLE_HOME é o endereço do nosso server.

PROGRAM é o programa que faz a comunicação com os serviços ODBC. Em muitos post’s, o nome indicado aqui é outro, mas por se tratar de versões anteriores. Atualmente, este é o nome correto.

No próximo bloco de configuração, o que nos interessa são as linhas:

LISTENER_MSSCONN =

… É a primeira linha do bloco, que descreve quais protocolos, host e porta serão atendidos pelo

listener que estamos criando. Deve ter exatamente o nome do Listener, identificado no primeiro bloco.

(ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6QTHL5D)(PORT = 1522))

… Protocolo TCP, Host e porta. Note que usamos uma porta diferente da porta padrão, que é 1521. Deste modo, colocamos o listener do outro banco “ouvindo” em uma porta diferente.

*** Muito importante! Não esqueça de abrir uma regra de entrada para esta porta no seu Firewall. Do contrário, nada de acesso.

O próximo arquivo é o tnsnames.ora, e merece um pouco mais de atenção. Mas isso por um

detalhe que a princípio não é muito fácil de encontrar na documentação. Pelo menos, eu não encontrei.

O arquivo de exemplo que a Oracle disponibiliza, é bem mais simples do que veremos a seguir.

Tem poucas linhas. E neste ponto, para piorar, encontramos uma outra fonte de confusão. Após terminar de alterar os arquivos, devemos copiar para a pasta final, indicada anteriormente. Só que neste local, já existem arquivos com o formato adequado e a extensão .ora, sem o .sample. E dentro, as configurações são coerentes com os serviços e listener que estão atualmente em uso por nosso banco Oracle. Inclusive, vemos ali o “XE”, que é justamente a instância ativa de nosso banco de dados. Então, o que devemos fazer ?

1)

Tentei, e foi péssimo. Não temos bons exemplos disponíveis de configuração para mais de um listener, pelo menos não no mesmo arquivo;

Mixar as configurações:

2) Criar arquivos diferentes:

Nada sobre isso também. Acredito que seja possível, mas como fugiria dos nomes padronizados, provavelmente, precisariamos configurar outros arquivos para identificar nosso listener. Muito complicado.

Foi então que, depois de inúmeras tentativas, e já quase desistindo, me deparei com uma resposta de um post, dentre tantas, onde a pessoa relatava justamente este problema. Foi quando alguém comentou que os serviços default do banco Oracle, não precisam de arquivo de configuração, e que teoricamente, se eliminássemos aqueles arquivos, o banco de dados continuaria funcionado da mesma forma. Se isso fosse verdade, então, poderíamos substituir completamente os arquivos da pasta pelos arquivos do nosso listener, e não teríamos problemas.

Primeiro, fiz um teste. Mudei o nome dos arquivos e das extensões, e reiniciei o banco, já me preparando para o pior. Surpresa! Tudo funcionando normalmente. Então a informação estava correta. Não entendi o motivo de ter estes arquivos neste local. Aparenta ser uma contiuação dos exemplos, como se na primeira pasta ficassem os arquivos de exemplo originais, e nesta última, os arquivos de exemplo modificados, em seu formato final, mas ainda sem função.

Deixando de lado as suposições, modifiquei o último arquivo, o tnsnames.ora, que ficou assim:

XE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6QTHL5D)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)

)

)

EXTPROC_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))

)

(CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO)

)

)

ORACLR_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))

)

(CONNECT_DATA = (SID = CLRExtProc) (PRESENTATION = RO)

)

)

LISTENER_MSSCONN = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6QTHL5D)(PORT = 1522)) (CONNECT_DATA = (SID = mssconn)

)

(HS = OK)

Neste caso, o que realmente nos interessa é o seguinte bloco:

LISTENER_MSSCONN = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6QTHL5D)(PORT = 1522)) (CONNECT_DATA = (SID = mssconn)

)

(HS = OK)

)

Este bloco é relativo ao nosso listener. Se houver mais linhas a partir daí, apague. O arquivo deve ficar exatamente desta forma.

Note novamente o nome do listener no início do bloco, o protocolo, o nome do host e a porta escolhida. Mais abaixo, temos o SID, que é novamente, o nome da nossa fonte de dados ODBC.

Não esquecer da linha HS = OK, que ativa realmente os heterogeneous services.

Agora, com tudo configurado, precisamos reiniciar o serviço de listener do Oracle, e iniciar o nosso listener. Abra uma janela de linha de comando do windows, em modo administrador, e vamos lá. Digite os seguintes comandos:

- lsnrctl reload (para reiniciar os serviço de listener)

- lsnrctl start listener_mssconn (para iniciar o nosso listener) Tudo estando configurado corretamente, você verá uma série de linhas de diagnóstico, indicando que está tudo ok. Podemos ver novamente este resultado, com o seguinte comando:

lsnrctl status listener_mssconn

O resultado deve ser este:

Podemos ver novamente este resultado, com o seguinte comando: lsnrctl status listener_mssconn O resultado deve ser

Este comando confirma o nome do listener, informa a quanto tempo está funcionando, bem como o arquivo de configuração que está sendo usado (C:

\oraclexe\app\oracle\product\11.2.0\server\network\admin\listener.ora), o servidor, protocolo e porta. Tudo ok.

Também podemos fazer outro teste para ter certeza de que a conexão é possível, antes de partirmos para o Apex. Digite o comando:

tnsping listener_mssconn 5

O resultado deverá ser este:

tnsping listener_mssconn 5 O resultado deverá ser este: O comando tenta conectar a fonte de dados,

O comando tenta conectar a fonte de dados, envia 5 pings, mede o tempo e informa o resultado.

Tudo ok também.

Você pode ainda fazer testes e criar um database link diretamente usando o utilitário de linha de comando sqlplus, mas vamos direto ao Apex para abreviarmos o processo.

Antes de poder criar o Database link, você deve dar a permissão ao schema, ou nome do workspace onde você pretende cria-lo, com o comando grant, utilizando o sqlplus, conectado como sysdba. Assim:

grant create database link to <nome_do_workspace_apex>;

Já no ambiente do Apex, na aba SQL Workshop, em Object Browser, você pode usar um Wizard e criar um Database link para utilizar nos reports e forms do seu aplicativo. Mas francamente, o wizard traz algumas opções a mais, que não consegui utilizar da maneira correta. Assim, preferi usar um comando direto, na aba SQL Commands, do SQL Workshop. O comando é este, muito simples:

CREATE DATABASE LINK “MSSERVER50" CONNECT TO “SA" IDENTIFIED BY “SENHA" USING “listener_mssconn”;

O resultado é a criação de um Database link, com o nome MSSERVER50, que você pode usar em qualquer query sql daí em diante. Usando o nosso banco de dados de exemplo do SQL Server, uma consula a tabela estados, ficaria assim:

SELECT * FROM estados@msserver50;

Abaixo, as telas finais da configuração:

ficaria assim: SELECT * FROM estados@msserver50; Abaixo, as telas finais da configuração: Criação do Database Link.

Criação do Database Link.

ficaria assim: SELECT * FROM estados@msserver50; Abaixo, as telas finais da configuração: Criação do Database Link.

Depois de criar um Interactive Report no Apex, usar como fonte de dados um SQL Query, no formato do exemplo.

O resultado final, será um relatório e formulário usando a tabela estados do SQL Server como se

fosse uma tabela nativa do Oracle.

do SQL Server como se fosse uma tabela nativa do Oracle. Até o momento não percebi

Até o momento não percebi nenhuma diferença de tratamento ou de performance, mas é claro que é apenas uma tabela pequena de teste. Mas relatos em fóruns também confirmam que o desempenho continua excelente.

Em relação ao tratamento dos dados, a única diferença que ví foi usando a linha de comando diretamente, onde as colunas precisam estar entre aspas, do contrário, comandos de update ou insert não funcionam.

É isso. O resultado final é realmente simples. Infelizmente, alguns pontos não tão bem

documentados ou explicados, transformam uma tarefa que poderia ser relativamente fácil, em algo desnecessariamente complicado. Então, justamente por isso, pretendo continuar documentando sempre que possível estes pequenos detalhes, mas que são tão importantes para que possamos realmente usar os recursos que temos a disposição.