Para melhor visualização, recomendo resolução de no mínimo 1280 x 800 e navegador Mozilla Firefox


quinta-feira, 2 de julho de 2009

Abordando o uso de Database Links em conexões heterogêneas. Acessando o PostgreSQL à partir do Oracle ...

Por Eduardo Legatti

Olá,

Para quem utiliza o serviço heterogêneo de conectividade "heterogeneous services" (hsodbc) para a realização de conexão entre um banco de dados Oracle e um banco de dados não-oracle, perceberá que no Oracle 11g o programa hsodbc foi substituído pelo dg4odbc (Database Gateway for ODBC). Percebi isso quando tentei, para fins de teste, "interligar" um banco de dados Oracle 11g à um banco de dados PostgreSQL. Lembro-me de que alguns anos atrás, não tive maiores problemas ao realizar este tipo de conexão entre um Oracle 10g (instalado em um Suse Linux 32 bits) e um banco de dados PostgreSQL 7x. Naquela época fiz uso das bibliotecas genéricas UNIXODBC. Hoje, utilizando o Oracle 11g em uma plataforma 64 bits, e após ter realizado algumas tentativas mal sucedidas utilizando o UNIXODBC, acabei apelando por fazer o uso de uma versão para avaliação de bibliotecas de terceiros. No mais, neste artigo, irei demonstrar os passos que realizei para acessar um banco de dados PostgreSQL 8.2.4 através de um objeto (database link) criado à partir do Oracle 11g (11.1.0.7) 64 bits instalado em um Linux CentOS release 5.2.

Como eu mencionei o termo (database link), primeiramente irei fazer uma breve apresentação sobre esse objeto:

Um database link (link de banco de dados) é um tipo especial de objeto criado em um esquema de banco de dados Oracle que permite o acesso direto a objetos de outro banco de dados, seja ele Oracle (homogêneo) ou não (heterogêneo).



Um database link geralmente é utilizado para suportar conexões utilizadas freqüentemente em bancos de dados remotos. Este objeto, na verdade, especifica o descritor de conexão a ser utilizado em uma conexão e também pode especificar o nome de usuário a ser conectado ao banco de dados remoto. Vale a pena salientar que, no geral, se utiliza links de banco de dados de forma a criar objetos locais (como views ou sinônimos) que acessam bancos de dados remotos.

Os sinônimos locais para objetos remotos, fornecem transparência de localização para os usuários locais do banco de dados, ou seja, quando um link de banco de dados é referenciado diretamente ou através de um sinônimo ou uma view, a instrução SQL é enviada e executada em uma nova sessão no banco de dados remoto. Ao ser executada, os dados são retornados para a sessão no banco de dados de origem.

Os links de banco de dados podem ser criados como links públicos (por DBA's) tornando os mesmos disponíveis para todos os usuários de banco de dados local ou como links privados. Para a criação deste objeto, se utiliza a sintaxe abaixo:

CREATE [ SHARED ] [ PUBLIC ] DATABASE LINK dblink
[ CONNECT TO
{ CURRENT_USER
| user IDENTIFIED BY password [ dblink_authentication ]
}
| dblink_authentication
]
[ CONNECT TO
{ CURRENT_USER
| user IDENTIFIED BY password [ dblink_authentication ]
}
| dblink_authentication
]...
[ USING connect_string ] ;

Por exemplo, o comando abaixo iria criar um link de banco de dados público chamado DBLINK:

SQL> create public database link DBLINK
2 connect to SCOTT identified by TIGER
3 using 'DB02';

onde, 'DB02' é o nome de serviço de banco dados existente no arquivo TNSNAMES.ORA local do meu servidor Oracle, na qual estão configuradas as informações da localização do servidor de banco de dados remoto.

Para utilizar esse database link, bastaria apenas adicioná-lo como sufixo aos nomes das tabelas como demonstrado na criação da view abaixo:

SQL> create view emp_remoto
2 as
3 select * FROM emp@DBLINK
4 where cod_dept > 10;

Podemos ver no exemplo acima que a cláusula "FROM" refere-se à EMP@DBLINK, onde, EMP é a tabela de destino, e DBLINK o objeto (database link) que contém as informações "encapsuladas" das informações do banco de dados de destino.

A propósito, no exemplo anterior foi criada uma view de banco de dados (emp_remoto), com o objetivo de simular uma regra de negócio na qual seria limitado os registros que os usuários poderiam recuperar, mas, se nenhuma restrição desse tipo for necessária, então poderíamos criar um sinônimo público como mostrado pelo comando abaixo:

SQL> create public synonym emp_remoto for emp@DBLINK;

Os usuários locais que consultarem o sinônimo público local EMP_REMOTO terão suas consultas automaticamente redirecionadas à tabela EMP do banco de dados remoto e, portanto, de forma transparente.

Irei demonstrar abaixo um exemplo prático na qual criarei um database link em um banco de dados Oracle 10g Express Edition para permitir acesso a um banco de dados Oracle 11g instalado em outro servidor. Observe que passarei a string de conexão diretamente no comando de criação do database link, sem a necessidade de ter definido previamente um serviço TNS de banco de dados, referente à instância Oracle remota no arquivo local TNSNAMES.ORA:

oracle@xe-developer:~> sqlplus / as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Qui Jul 02 08:03:52 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Conectado a:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

SQL> create database link dblink11g
2 connect to system identified by minhasenha
3 using '(description = (address = (protocol = tcp)
4 (host = 11g_production)(port = 1521))
5 (connect_data = (sid = bdprod)))';

Vínculo de banco de dados criado.

-- Selecionando informações do banco de dados local
SQL> select instance_name,host_name from v$instance;

INSTANCE_NAME HOST_NAME
---------------- --------------------------------------
XE xe-developer


-- Selecionando informações do banco de dados remoto
SQL> select instance_name,host_name from v$instance@dblink11g;

INSTANCE_NAME HOST_NAME
---------------- --------------------------------------
BDPROD 11g_production

Bom, depois dessa breve introdução ao conceito de Database Links, vamos voltar ao assunto que originou este artigo ...

Para início, é bom ficar claro que na versão 11g do banco de dados Oracle, não será mais possível executar o utilitário abaixo como nas versões anteriores:

[oracle@Linux ~]$ hsodbc

Oracle Corporation --- QUINTA-FEIRA JUL 02 2009 08:17:25.104

Heterogeneous Agent Release 10.2.0.1.0 - Production Built with
Driver for ODBC

Caso alguma tentativa de acesso ao programa hsodbc seja realizada utilizando o Oracle 11g, o erro abaixo será retornado:

[oracle@Linux ~]$ hsodbc
-bash: hsodbc: command not found

Portanto, deverá ser utilizado o programa dg4odbc que, inclusive, poderá ser instalado e utilizado em versões anteriores ao Oracle 11g conforme a nota 466228.1 do Oracle Metalink:

"Starting with 11g Oracle now provides a Database Gateway for ODBC for 32bit Linux operating systems. The difference between the older product (Generic Connectivity or sometimes also called HSODBC) is DG4ODBC is now a stand alone product. It is no longer required to have DG4ODBC running on the same machine as the Oracle database. The gateway is certified also for older Oracle releases 9.2.0.8, 10.1.0.5, or 10.2.0.3. But please be aware those pre-11g Oracle databases require a patch to work properly with V11 Gateways."

[oracle@Linux ~]$ dg4odbc

Oracle Corporation --- QUINTA-FEIRA JUL 02 2009 08:20:35.379

Heterogeneous Agent Release 11.1.0.7.0 - 64bit Production Built with
Oracle Database Gateway for ODBC

[oracle@Linux ~]$

Após ter realizado o download das bibliotecas (64 bits) de avaliação do site em questão, irei iniciar a instalação das mesmas:

[root@Linux tmp]# tar xzvf evlinuxx64.tar.Z
autorun.dat
install.mi
unixmi.ksh
etc/lang/
etc/lang/msg.dat
etc/lang/license.txt
etc/lang/useng.msg
etc/lic/
etc/lic/makelica
etc/lic/makeliclx
etc/lic/makelicl
etc/lic/makelich
etc/lic/makelicsx
etc/lic/makelics
linuxx/ICULicense.txt
linuxx/mysqllicense.txt
linuxx/ODBC64FIXES.TXT
linuxx/ODBC64README.TXT
linuxx/scr1
linuxx/tarfiles/
linuxx/tarfiles/teradata.tar
linuxx/tarfiles/mssql.tar
linuxx/tarfiles/oracle.tar
linuxx/tarfiles/sybase.tar
linuxx/tarfiles/mysql.tar
linuxx/tarfiles/oraclewp.tar
linuxx/tarfiles/linuxx.tar
linuxx/tarfiles/greenplum.tar
linuxx/tarfiles/drda.tar
linuxx/tarfiles/postgresql.tar
linuxx/tarfiles/infcl.tar

[root@Linux tmp]# ksh unixmi.ksh
DataDirect Technologies Product Setup is preparing....

English has been set as the installation language.

Log file : /tmp/logfile.9216.1
----------------------------------------------------------------------
DataDirect Technologies Product Setup (DPS)
for UNIX operating systems
----------------------------------------------------------------------

The following operating system has been detected:

LinuxX64
Is this the current operating system on your machine (Y/N) ? [Y]
END USER PRODUCT LICENSE AGREEMENT ("AGREEMENT")

DataDirect EULA Revised 02/12/2009

Enter YES to accept the above agreement : yes
Please enter the following information for proper registration.

In the Key field, enter either EVAL or the Key provided.

Name :EVAL
Company :legatti - evaluation
Serial Number :EVAL
Key :EVAL

You can install drivers for all supported databases or
install a single driver.

Drivers for All Supported Databases includes one driver for each supported database.
In the case of Oracle, DataDirect Connect64 for ODBC 6.0 SP1 has two available drivers
that support the database--a wire protocol driver that does not require any database
client software to connect to the database, and a client-based driver that does require
client software. By default, the Oracle Wire Protocol driver is installed.

Single Driver allows you to choose one from any of the DataDirect Connect64 for
ODBC 6.0 SP1 drivers, including the client-based Oracle driver.

If you want to evaluate more than one single driver, you will have the opportunity to do
so after completion of the initial installation.

1. Drivers for All Supported Databases
2. Single Driver
Please enter an option [1]:2


1. DB2 Wire Protocol
2. Greenplum Wire Protocol
3. Informix Wire Protocol
4. MySQL Wire Protocol
5. Microsoft SQL Server Wire Protocol
6. Oracle Wire Protocol
7. PostgreSQL Wire Protocol
8. Sybase Wire Protocol
9. Teradata (XE)
10. Oracle (client)
Please enter driver option:7

You have chosen to eval the PostgreSQL Wire Protocol driver.

To change this information, enter C. Otherwise, press Enter to continue. :

You have chosen to eval the PostgreSQL Wire Protocol driver.

To change this information, enter C. Otherwise, press Enter to continue. :
DataDirect Technologies Product Setup is preparing the installation.
Choose a temporary directory.

Enter the full path to the temporary install directory.[/tmp]:
Checking for available space...

There is enough space.
Extracting files...

Choose a destination directory.
Enter the full path to the install directory.[/opt/Connect64forODBC60]:
Checking for available space...

There is enough space.
Extracting files...

Creating license file......


DataDirect Technologies Product Setup successfully removed all of the temporary files.


Thank you for using DataDirect Technologies products.

Installation ended successfully.

Would you like to install another product (Y/N) ? [Y]N
Thank you for using DataDirect Technologies products.

Installation ended successfully.

Após realizada a instalação das bibliotecas, iniciarei a configuração dos arquivos odbc.ini e odbinst.ini como demonstrado abaixo:

[root@Linux /]# cd /opt/Connect64forODBC60/

-- Arquivo odbc.ini
[root@Linux Connect64forODBC60]# cat odbc.ini
[ODBC Data Sources]
PostgreSQL Wire Protocol=DataDirect 6.0 PostgreSQL Wire Protocol

[ODBC]
IANAAppCodePage=4
InstallDir=/opt/Connect64forODBC60
Trace=0
TraceFile=odbctrace.out
TraceDll=/opt/Connect64forODBC60/lib/odbctrac.so

[PostgreSQL Wire Protocol]
Driver=/opt/Connect64forODBC60/lib/ddpsql24.so
Description=DataDirect 6.0 PostgreSQL Wire Protocol
ApplicationUsingThreads=1
ConnectionReset=0
ConnectionRetryCount=0
ConnectionRetryDelay=3
Database=bdlegatti
EnableDescribeParam=1
EncryptionMethod=0
ExtendedColumnMetadata=0
FailoverGranularity=0
FailoverMode=0
FailoverPreconnect=0
FetchRefCursor=1
FetchTSWTZasTimestamp=0
FetchTWFSasTime=0
HostName=10.10.10.2
LoadBalanceTimeout=0
LoadBalancing=0
LoginTimeout=15
LogonID=postgres
MaxPoolSize=100
MinPoolSize=0
Password=postgres
Pooling=0
PortNumber=5432
QueryTimeout=0
ReportCodepageConversionErrors=0
TransactionErrorBehavior=1
ValidateServerCertificate=1
XMLDescribeType=-10


-- Arquivo odbcinst.ini
[root@Linux Connect64forODBC60]# cat odbcinst.ini
[ODBC Drivers]
DataDirect 6.0 PostgreSQL Wire Protocol=Installed

[ODBC Translators]
OEM to ANSI=Installed

[Administrator]
HelpRootDirectory=/opt/Connect64forODBC60/adminhelp

[ODBC]
#This section must contain values for DSN-less connections
#if no odbc.ini file exists. If an odbc.ini file exists,
#the values from that [ODBC] section are used.

[DataDirect 6.0 PostgreSQL Wire Protocol]
Driver=/opt/Connect64forODBC60/lib/ddpsql24.so
Setup=/opt/Connect64forODBC60/lib/ddpsql24.so
APILevel=1
ConnectFunctions=YYY
DriverODBCVer=3.52
FileUsage=0
HelpRootDirectory=/opt/Connect64forODBC60/help
SQLLevel=0

O próximo passo é configurar os arquivos listener.ora e tnsnames.ora de forma a fazer referência ao serviço de banco de dados que chamarei de POSTGRESQL conforme demonstrado no exemplo abaixo:

[oracle@Linux ~]$ cd $ORACLE_HOME/network/admin

-- Arquivo listener.ora
[oracle@Linux admin]$ cat listener.ora
# listener.ora Network Configuration File: $ORACLE_HOME/network/admin/listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = BD01)
(ORACLE_HOME = /u01/app/oracle/product/11.1.0/db_1)
(SID_NAME = BD01)
)
(SID_DESC =
(SID_NAME= POSTGRESQL)
(ORACLE_HOME = /u01/app/oracle/product/11.1.0/db_1)
(PROGRAM=dg4odbc)
(ENVS=LD_LIBRARY_PATH = /opt/Connect64forODBC60/lib:
/u01/app/oracle/product/11.1.0/db_1/lib:
/lib:/usr/lib:/etc)
)
)

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = Linux)(PORT = 1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

Apenas como observação, caso uma versão anterior do Oracle (10g, 9i ...) esteja sendo utilizada, no trecho do código acima deverá ser substituído a linha onde está (PROGRAM=dg4odbc) para (PROGRAM=hsodbc).

-- Arquivo tnsnames.ora
[oracle@Linux admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: $ORACLE_HOME/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

BD01 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = Linux)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = BD01)
)
)

PG_SERVICE =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST = Linux)(PORT=1521))
(CONNECT_DATA=(SID=POSTGRESQL))
(HS=OK)
)

Após definida a configuração dos arquivos listener.ora e tnsnames.ora, irei inicializar o processo listener conforme demonstrado no exemplo abaixo:

-- Inicialização do processo listener
[oracle@Linux ~]$ lsnrctl start

LSNRCTL for Linux: Version 11.1.0.7.0 - Production on 02-JUL-2009 09:10:53

Copyright (c) 1991, 2008, Oracle. All rights reserved.

Iniciando /u01/app/oracle/product/11.1.0/bd01/bin/tnslsnr: aguarde...

TNSLSNR for Linux: Version 11.1.0.7.0 - Production
O arquivo de parâmetros do sistema é $ORACLE_HOME/network/admin/listener.ora
Atendendo em: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=Linux)(PORT=1521)))
Atendendo em: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))

Estabelecendo conexão com (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=Linux)(PORT=1521)))
STATUS do LISTENER
------------------------
Apelido LISTENER
Versão TNSLSNR for Linux: Version 11.1.0.7.0 - Production
Data Inicial 02-JUL-2009 09:10:53
Funcionamento 0 dias 0 hr. 0 min. 0 seg
Nível de Análise off
Segurança ON: Local OS Authentication
SNMP OFF
Arq. Parâm. Listn. /u01/app/oracle/product/11.1.0/db_1/network/admin/listener.ora
Resumo de Atendimento...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=Linux)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Resumo de Serviços...
O serviço "BD01" tem 1 instância(s).
Instância "BD01", status UNKNOWN, tem 1 handler(s) para este serviço...
O serviço "POSTGRESQL" tem 1 instância(s).
Instância "POSTGRESQL", status UNKNOWN, tem 1 handler(s) para este serviço...
O comando foi executado com êxito

Afim de evitar quaisquer erros de acesso às bibliotecas ODBC instaladas, ou qualquer outra surpresa, irei atualizar também arquivo de profile do usuário "oracle" com o caminho das bibliotecas ODBC instaladas anteriormente:

[oracle@Linux ~]$ cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

export TEMP=/tmp
export TMPDIR=/tmp
export ORACLE_BASE=/u01/app/oracle
export ORACLE_SID=BD01
export ORACLE_HOME=$ORACLE_BASE/product/11.1.0/db_1
export PATH=$PATH:$ORACLE_HOME/bin:$ORACLE_HOME/ctx/bin:/opt/Connect64forODBC60/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/ctx/lib:$ORACLE_HOME/lib:
/opt/Connect64forODBC60/lib
export NLS_LANG="BRAZILIAN PORTUGUESE_BRAZIL.WE8ISO8859P1"
export NLS_DATE_FORMAT=DD/MM/YYYY

Agora vem a parte em que criamos o arquivo de configuração para que seja possível a realização da conexão entre o Oracle e o banco de dados remoto (no meu caso, o PostgreSQL). Os programas dg4odbc/hsodbc geralmente procuram por um arquivo init[SID].ora localizado em $ORACLE_HOME/hs/admin. No meu caso, o SID que utilizei no arquivo listener.ora foi POSTGRESQL, portanto o arquivo a ser criado será initPOSTGRESQL.ora conforme demonstrado no trecho de código abaixo:

[oracle@Linux ~]$ cd $ORACLE_HOME/hs/admin

[oracle@Linux admin]$ cat initPOSTGRESQL.ora
# 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 = "PostgreSQL Wire Protocol"
HS_FDS_TRACE_LEVEL = OFF
HS_LANGUAGE = "BRAZILIAN PORTUGUESE_BRAZIL.WE8ISO8859P1"
HS_NLS_DATE_FORMAT = "DD/MM/YYYY HH24:MI:SS"
HS_OPEN_CURSORS = 200
HS_FDS_SHAREABLE_NAME = /opt/Connect64forODBC60/lib/libodbc.so
#
# ODBC specific environment variables
#
set ODBCINI=/opt/Connect64forODBC60/odbc.ini
set ODBCINSTINI=/opt/Connect64forODBC60/odbcinst.ini
set LD_LIBRARY_PATH=/opt/Connect64forODBC60/lib:
/u01/app/oracle/product/11.1.0/bd01/lib:
/lib:/usr/lib
set PATH=/opt/Connect64forODBC60/lib:/u01/app/oracle/product/11.1.0/bd01/lib:
/lib:/usr/lib
#
# Environment variables required for the non-Oracle system
#
#set [envvar]=[value]

Basicamente, os valores e parâmetros acima mais importantes são:

* set ODBCINI define o local onde está localizado o arquivo odbc.ini
* HS_FDS_CONNECT_INFO aponta para o nome da fonte de dados ODBC (DSN).
* HS_FDS_SHAREABLE_NAME aponta para a biblioteca de driver ODBC compartilhada.

Caso algum problema ocorra na tentativa de realizar a conexão com o banco de dados remoto, setando o parâmetro HS_FDS_TRACE_LEVEL com um valor maior que zero ou (ON ou DEBUG) é que nos permitirá verificar com mais detalhes o que aconteceu de errado. Para maiores informações sobre estes e outros parâmetros, acesse a página Oracle Database Gateway for ODBC User's Guide.

Por fim, após realizado todo este trabalho acima, bastará agora, para fins de teste, criar um link de banco de dados privado no meu banco de dados Oracle local que chamarei de "pgsql" para, então, realizar o teste de conexão com o banco de dados remoto. Vale a observação de que eu já criei e populei no banco de dados remoto (PostgreSQL), uma tabela de teste chamada "emp" (empregados) com a estrutura a seguir:

create table emp
(
cod smallint NOT NULL,
data_cadastro date NOT NULL,
nome varchar(80) NOT NULL,
constraint pk_emp primary key (cod)
);

-- Criando o link de banco de dados (database link)
C:\>sqlplus system/*********

SQL*Plus: Release 11.1.0.6.0 - Production on Qui Jul 02 09:25:44 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create database link pgsql connect to "postgres" identified by "postgres"
2 using 'PG_SERVICE';

Vínculo de banco de dados criado.

-- Realizando o teste de conexão com o PostgreSQL
SQL> select * from "emp"@pgsql;

cod data_cadas nome
---------- ---------- ---------------------------------
1 25/06/2009 EDUARDO
2 28/06/2009 MARIA
3 21/06/2009 ANGELA
4 29/06/2009 LAURA


SQL> delete from "emp"@pg where "cod"=2;


1 linha deletada.

SQL> commit;

Commit concluído.

SQL> select * from "emp"@pgsql;

cod data_cadas nome
---------- ---------- ---------------------------------
1 25/06/2009 EDUARDO
3 21/06/2009 ANGELA
4 29/06/2009 LAURA

Em relação ao PostgreSQL, será necessário colocar os nomes das tabelas e colunas entre "aspas duplas", de forma a acessar os objetos do banco de dados, caso contrário, o erro abaixo será emitido:

SQL> select * from emp@pgsql;
select * from emp@pgsql
*
ERRO na linha 1:
ORA-00942: a tabela ou view não existe
[DataDirect][ODBC PostgreSQL Wire Protocol driver][PostgreSQL]ERROR: relation "EMP" does
not exist(File namespace.c;Line 221;Routine RangeVarGetRelid;)[DataDirect][ODBC
PostgreSQL Wire Protocol driver][PostgreSQL]Failed transaction.
The current transaction rolled back.
ORA-02063: precedendo 2 lines a partir de PGSQL


SQL> select owner,table_name from all_tables@pgsql where table_name='emp';

OWNER TABLE_NAME
--------------- ------------------------------
public emp


SQL> desc "emp"@pgsql
Nome Nulo? Tipo
-------------------------- --------- ----------------------------
cod NOT NULL NUMBER(5)
data_cadastro NOT NULL DATE
nome NOT NULL VARCHAR2(80)


SQL> select nome from "emp"@pgsql;
select nome from "emp"@pgsql
*
ERRO na linha 1:
ORA-00904: "NOME": identificador inválido

SQL> select "nome" from "emp"@pgsql;

nome
-------------------------------------------------
EDUARDO
ANGELA
LAURA


SQL> create view emp_remoto
2 as
3 select * from "emp"@pgsql;

View criada.

SQL> select * from emp_remoto;

cod data_cadas nome
---------- ---------- ---------------------------
1 25/06/2009 EDUARDO
3 21/06/2009 ANGELA
4 29/06/2009 LAURA


SQL> create synonym emp for "emp"@pgsql;

Sinônimo criado.

SQL> select * from emp;

cod data_cadas nome
---------- ---------- ---------------------------
1 25/06/2009 EDUARDO
3 21/06/2009 ANGELA
4 29/06/2009 LAURA


SQL> create table "emp2"@pgsql (id integer);
create table "emp2"@pgsql (id integer)
*
ERRO na linha 1:
ORA-02021: as operações DDL não são permitidas em um banco de dados remoto

Para concluir, podemos ver acima que o último comando falhou, pelo fato de não ser possível qualquer operação DDL (Data Definition Language) no banco de dados remoto.



26 comentários:

Unknown disse...

muito bom seu post,
apenas uma duvida, a onde posso baixar as bibliotecas?

Eduardo Legatti disse...

Olá Josué,

Você vai ter que dar uma pesquisada, mas na época eu baixei os drivers do site http://www.datadirect.com/

Você já tentou o link abaixo?

http://www.datadirect.com/products/odbc/postgresql/index.html

Abraços e boa sorte

Legatti

NT disse...

Eduardo, pra eu acessar o postgreSQL tenho que usar um driver de terceiros?? Tenho que comprar o driver do site datadirect.com??? A oracle não provê nenhuma solução pra acessar o postgre???

Eduardo Legatti disse...

Olá Neto,

Na época desse artigo (2009), o único driver que eu conseguia usar era o da datadirect.com. Acredito que hoje em dia o unixODBC deva ter evoluído.

Tente pesquisar "Oracle Gateway for ODBC for PostgreSQL", pois com certeza você vai encontrar alguém que já tenha utilizado o unixODBC com sucesso.

Abraços

Legatti

NT disse...

Olá Eduardo,
consegui me conectar no postgres pelo oracle usando o unixODBC.
Agora me surgiu uma outra duvida a respeito da sintaxe no comando select.
Não sei se vc sabe mais o postgres também tem o conceito de schemas,
então como eu faço pra acessar as tabelas de um schema especifico usando o db_link??
Por que quero usar isso?
No postgres existe uma feature que me permite fazer um select sem passar o owner da tabela
e ele faz a pesquisa do nome da tabela nos schemas daquele banco de dados.
E claro que podem existir 2 tabelas com o mesmo nome em schemas diferentes.


se eu fizer: select * from "tabela"@postgres
funciona perfeitamente.
Mas seu fizer: select * from "owner"."tabela"@postgres
ou
select * from "owner.tabela"@postgres
não funciona!!!
Vc ja passou por isso??

Eduardo Legatti disse...

Olá Netto,

Já faz muito tempo que não uso o PostgreSQL. No mais, realmente não há como qualificar (colocar o nome do schema) na frente de uma tabela via DBLINK. No Postgres eu sei que podemos configurar o schema search path. Bom, não tenho certeza, mas isso por si só já não funcionaria? Caso não funcione, talvez você tenha que criar views dentro de um schema de sua escolha referenciando cada tabela de outros schemas na qual se deseja acessar via DBLINK. Faça os testes necessários, pois com certeza deverá haver alguma solução.

Abraços e até mais ...

Legatti

Unknown disse...

Legatti, estou com uma dúvida. Foi feito uma troca de servidor de banco de dados de uma filial do meu trabalho. A requisição ao BD é feita via dblink, porém está gerando um erro que os dois servidores x1 e x2 estão fazendo requisições para um dblink. O host foi alterado no tnsnames do servidor novo, no caso x2. O que pode está acontecendo para gerar esse erro?
Obrigado

Eduardo Legatti disse...

Olá,

Informações insuficientes. Qual é mesmo o erro ORA-?

Abraços

Legatti

Anônimo disse...

Olá a todos.

Alguém tem notícia do inverso, para o MySQL conectar no ORACLE e poder executar um select?

Obrigado

Reinaldo

Eduardo Legatti disse...

Olá Reinaldo,

Acho difícil, mas você pode dar uma pesquisada em "FEDERATED Storage Engine" do MySQL.

Abraços

Legatti

Unknown disse...

Show de bola o artigo.
Mais para fazer com que o mySql sejá o banco que pegue os dados do oracle, você teria algum artigo, ou algum passo a passo de como proceder ?

Abs;

Eduardo Legatti disse...

Olá Renan,

Não conheço uma forma simples de fazer isso à partir do MySQL. A opção que eu vejo no seu caso seria você criar um DBLINK do Oracle para o MySQL. Nesse caso você pode criar rotinas agendadas que enviaria os dados para uma tabela no MySQL e à partir daí você manipularia essas informações no MySQL. Uma outra forma seria você fazer com que o Oracle gerasse arquivos ".csv" com os dados que você precisa para então importar isso no MySQL. À partir do MySQL 5.1 existe uma engine chamada "CSV Storage Engine" que permite você ler diretamente de arquivos ".csv". Dá uma pesquisada que você pode encontrar algumas soluções.

Abraços

Legatti

Unknown disse...

Eduardo Legatti boa tarde.

Tenho um Database Link no Oracle lendo um banco de dados no SQL. Consigo fazer um "select" em uma tabela X no banco do SQL, mas não consigo colocar uma clausula "where" para restringir a consulta. A mensagem de erro diz que o campo não existe. Você pode me ajudar neste caso? Acredito que seja somente a sintaxe mas eu não soube como ajustar.
Obrigado

Exemplo da select;

select * from Documento_rec@dbl_pir_ERP where cod_documento_sg = '67941'

Eduardo Legatti disse...

Olá Francisnei,

Você tem um DBLINK no Oracle apontando para um banco de dados SQL Server, certo? A mensagem de erro é do Oracle ou do SQL Server?

Bom, não estou vendo nada de errado na sua instrução SELECT. Quando você faz um "SELECT *", os nomes das colunas aparecem em maiúsculo ou minúsculo? Você já tentou colocar o nome da coluna entre aspas duplas? Talvez você esteja passando por algum tipo de problema de "case sensitive".

Abraços

Legatti

Unknown disse...

Você tem um DBLINK no Oracle apontando para um banco de dados SQL Server, certo?
Sim.
A mensagem de erro é do Oracle ou do SQL Server?
Oracle.
Bom, não estou vendo nada de errado na sua instrução SELECT.
Quando você faz um "SELECT *", os nomes das colunas aparecem em maiúsculo ou minúsculo?
Iniciais em maiúsculo, o resto minúsculo.
Ex: Cod_Empresa_Sg, Cod_Documento, Descrição_Conta
Você já tentou colocar o nome da coluna entre aspas duplas?
Talvez você esteja passando por algum tipo de problema de "case sensitive".

Qualquer uma das instruções abaixo retorna o erro no Oracle:
ORA-00904: “Cod_Documento_Sg”: identificados inválido
select * from TI_documento@dbl_pir where "TI_documento"."Cod_Documento_SG" = '1234'
select * from TI_documento@dbl_pir where "Cod_Documento_SG" = '12345'

Eduardo Legatti disse...

Olá Francisnei,

Ainda acho que é algum problema de "case sensitive". O prlblema nao é a cláusula WHERE. Faça o teste no seu SELECT e em vez de "SELECT *", coloque o nome da coluna.

Exemplo:

select Cod_Documento_SG from TI_documento@dbl_pir;
select "Cod_Documento_SG" from TI_documento@dbl_pir;
select "COD_DOCUMENTO_SG" from TI_documento@dbl_pir;
select "cod_documento_sg" from TI_documento@dbl_pir;

Abraços,

Legatti

Unknown disse...

Legatti, o problema persiste. Percebi enquanto digitava que ao incluir o nome dos campos a sugestão automática do nome mostra apenas os nomes da tabela local. Ou seja, eu estou no oracle buscando uma tabela no SQL e é apresentado o nome dos campos no oracle e não do SQL.

Continuo tentando.

Eduardo Legatti disse...

Olá Francisnei,

Quanto ao "auto complete" em relação aos nomes de colunas e tabelas, vai depender da ferramenta que você está usando. Não sei se a ferramenta seria capaz de acessar via DBLINK o dicionário de dados do banco de dados heterogêneo de destino para buscar essas informações ;-)

Quanto ao seu problema, você vai ter que quebrar a cabeça aí. ;-)

Para resolver o seu problema temporariamente talvez você possa tentar o SQL abaixo:

select * from (select * from TI_documento@dbl_pir) where Cod_Documento_SG = 12345;

No exemplo acima, se der algum erro, veja se você consegue resolver colocando o nome da coluna e tabela entre aspas duplas.

Abraços,

Legatti

Unknown disse...

Legatti bom dia.

Enfim a rotina "rodou" sem problema. A sintaxe ficou assim:

SELECT * FROM TI_DOCUMENTO@dbl_pir T WHERE T."Cod_Documento_Sg" = 123456;

Obrigado por sua atenção e ajuda.
Obrigado também ao Luiz Cássio Alves pela atenção e pesquisas.

Eduardo Legatti disse...

Olá Francisnei,

Que bom que funcionou!! ;-)

Abraços e até mais ...

Legatti

Heric disse...

Olá, deu tudo certo seguindo seu tutorial.
Agora estou na dúvida com o seguinte.
Estou fazendo uma conexão remota com aplicações da empresa, abro o arquivo tnsnames e aponto pro ip fixo da iternet e Abre normalmente. Logo no erp e co sigo trabalhar de fora da empresa, que do estou na empresa mudo pro ip local da rede 192....
Queria saber como deixar os 2 ips sempre usar esta mudando. Quabdo estiver na empresa conectar pelo ip local, e quando estive fora conecta pelo ip fixo da Internet


Já tentei colocar os 2 porém da erro de tnsnames. Aí tenho que ficar mudando manualmente

Eduardo Legatti disse...

Olá Heric,

O exemplo abaixo não funcionou?

TNSBD01 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = x.x.x.x)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = x.x.x.x)(PORT = 1521))
)
(CONNECT_DATA =
(SID = BD01)
)
)


Abraços,

Legatti

Johnatas disse...

Parabéns pelo post, Eduardo. Procurando na internet, exatamente o contrário, encontrei seu post. Preciso criar uma conexão do Postgresql para o Oracle, preciso criar uma view no postgresql que veja uma tabela no Oracle, seria possível o contrário? Este procedimento funciona na minha necessidade? Agradeço desde já.

Eduardo Legatti disse...

Olá Johnatas,

Acredito que tenha alguma solução. Teste pesquisar por:"connecting to oracle from postgresql".

Caso não encontre nada, talvez uma opção seja gerar os dados no Oracle para um arquivo csv ou SQL e o PostgreSQL ler esse arquivo e importar os dados. Aí nesse caso vc agendaria esse procedimento para ser executado em uma certa periodicidade.

Abraços,

Legatti

Sadrake Gabriel disse...

Boa tarde, onde consigo o arquivo evlinuxx64.tar.Z ?
nao a url de download no site

Eduardo Legatti disse...

Esse artigo, já está bem antigo, então não sei se esse método ainda funcionaria. De qualquer forma, o e tiver odbc do postgresql pode ser baixado aqui.

https://odbc.postgresql.org/

Postagens populares