1. Introduction
1.1. Summary
This post shows how to create a database link between Oracle XE vs PostgreSQL1.2. Scenario
- Oracle Linux x86_64 server:
- IP: 192.168.1.20
- Oracle database instance SID=prod
- PostgreSQL Linux x86_64 server
- IP: 192.168.1.20
- PostgreSQL database = prod
1.3. Cookbook
- Connect to PostgreSQL and create user for database link and grant appropriated permission
- Connect to Oracle, install and configure Unix ODBC packages and drivers
- Configure Oracle Heterogeneous Service
- Create and test Oracle Database Link to PostgreSQL throught Oracle Heterogeneous Service
2. Step-by-Step
2.1. Connect to PostgreSQL and create user for database link and grant appropriated permission
a) Create PostgreSQL user used by Oracle dblink connection
postgres=# CREATE USER dblink_oracle WITH PASSWORD 'dblink_oracle';
CREATE ROLE
b) Grant connection to dblink user to appropriated PostgreSQL database
postgres=# GRANT CONNECT ON DATABASE prod TO dblink_oracle;GRANT
c) Grant to dblink user to appropriated schema and database objects permissions
prod=# GRANT USAGE ON SCHEMA schema1 TO dblink_oracle;GRANT
prod=# GRANT SELECT ON ALL TABLES IN SCHEMA schema1 TO dblink_oracle;
GRANT
prod=#
d) Disconnect and Connect with dblink user to test permissions given
prod=# \q-bash-4.2$ psql -h localhost -U dblink_oracle -W prod
Password for user dblink_oracle:
psql (9.3.5)
Type "help" for help.
prod=> select table_catalog, table_schema, table_name from information_schema.tables;
table_catalog | table_schema | table_name
---------------+--------------------+---------------------------------------
: : :
2.1. Connect to Oracle Server, install and configure Unix ODBC packages and drivers
a) Install packages required
# yum install unixODBC# yum install postgresql-odbc
b) Configure connection on ODBC.INI
# vim /etc/odbc.ini[DB_PGSQL]
Description = DB_PGSQL
Driver = PostgreSQL
Trace = False
TraceFil = /tmp/odbc.log
Database = prod
Servername = postgresql.mydomain.com
Username = dblink_oracle
Password = dblink_oracle
Port = 5432
ReadOnly = Yes
c) Configure driver on ODBCINST.INI
# cat /etc/odbcinst.ini# Example driver definitions
# Driver from the postgresql-odbc package
# Setup from the unixODBC package
[PostgreSQL]
Description = ODBC for PostgreSQL
Driver = /usr/lib/psqlodbc.so
Setup = /usr/lib/libodbcpsqlS.so
Driver64 = /usr/lib64/psqlodbc.so
Setup64 = /usr/lib64/libodbcpsqlS.so
FileUsage = 1
# Driver from the mysql-connector-odbc package
# Setup from the unixODBC package
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc5.so
Setup = /usr/lib/libodbcmyS.so
Driver64 = /usr/lib64/libmyodbc5.so
Setup64 = /usr/lib64/libodbcmyS.so
FileUsage = 1
d) Configure Oracle Heterogeneous Services init file on $ORACLE_HOME/hs/admin/initDB_PGSQL.ora
- Change user to oracle installation user on Unix
# su - oracle
$ id
uid=500(oracle) gid=500(dba) groups=500(dba)
$ echo $ORACLE_HOME
/u01/app/oracle/product/11.2.0/xe
$ ls -la $ORACLE_HOME/hs/admin
total 24
drwxr-xr-x 2 oracle oinstall 4096 Dec 20 2013 .
drwxr-xr-x 5 oracle oinstall 4096 Dec 20 2013 ..
-rw-r--r-- 1 oracle oinstall 1109 Sep 17 2011 extproc.ora
-rw-r--r-- 1 oracle oinstall 489 Sep 17 2011 initdg4odbc.ora
-rw-r--r-- 1 oracle oinstall 411 Dec 20 2013 listener.ora.sample
-rw-r--r-- 1 oracle oinstall 244 Dec 20 2013 tnsnames.ora.sample
- Let's use Oracle Heterogeneous Service default database gateway file 'initdg4odbc.ora' as base of 'initDB_PGSQL.ora'
- Configure key "HS_FDS_SHAREABLE_NAME" to point to appropriated binary installation of your system x86 32bit or 64bit. In my case, it was a 64bits installation '/usr/lib64'
- Configure environment variables if necessary. In my case, I needed to force CHARSET
$ cd $ORACLE_HOME/hs/admin
$ cp initdg4odbc.ora initDB_PGSQL.ora
$ vim initDB_PGSQL.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 = DB_PGSQL
HS_FDS_TRACE_LEVEL = off
HS_FDS_SHAREABLE_NAME = /usr/lib64/psqlodbc.so
#
# ODBC specific environment variables
#
set ODBCINI=/etc/odbc.ini
#
# Environment variables required for the non-Oracle system
#
#set <envvar>=<value>
set CHARSET = UTF8
e) before continuing with Oracle HS configuration, let's check if ODBC connection is working properly. We will use isql to connect throught ODBC connection and try some SQL statement on remote PostgreSQL database
$ -bash-4.1$ odbcinst -junixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /u01/oracle/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
$ isql DB_PGSQL dblink_oracle dblink_oracle
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> select table_catalog, table_schema, count(*) from information_schema.tables group by table_catalog, table_schema;
+---------------+--------------+---------------------+
| table_catalog | table_schema | count |
+---------------+--------------+---------------------+
: : :
f) Configure Oracle HS as database gateway on LISTENER.ORA
- Oracle has changed ( since version 10) binary file for HS(Heterogeneous Service) from 'hsodbc' to 'dg4odbc'. Before configure your LISTENER.ORA look for correct binary file for Oracle Database Gateway for Heterogeneous Service ODBC in $ORACLE_HOME/bin/*. In my case, binary file is 'dg4odbc'
$ ls -la $ORACLE_HOME/bin/hsodbc*
ls: cannot access /u01/oracle/app//product/11.2.0/dbhome_1/bin/hsodbc: No such file or directory
$ ls -la $ORACLE_HOME/bin/dg4odbc*
-rwxr-x--x 1 oracle oinstall 536297 Dec 20 2013 /u01/oracle/app//product/11.2.0/dbhome_1/bin/dg4odbc
$ cd $ORACLE_HOME/network/admin/
$ vim listener.ora
# listener.ora Network Configuration File:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/xe)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = DB_PGSQL)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/xe)
(PROGRAM = dg4odbc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle.mydomain.com)(PORT = 1521))
)
)
DEFAULT_SERVICE_LISTENER = (XE)
g) Configure TNSNAMES.ORA for HS
$ cd $ORACLE_HOME/network/admin/$ vim tnsnames.ora
DB_PGSQL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle.mydomain.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = DB_PGSQL)
)
(HS = OK)
)
h) Restart LISTENER
$ lsnrctl reloadLSNRCTL for Linux: Version 11.2.0.3.0 - Production on 27-FEB-2015 12:11:58
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
The command completed successfully
i) Create and test Oracle Database Link to PostgreSQL throught Oracle Heterogeneous Service
$ sqlplusSQL*Plus: Release 11.2.0.3.0 Production on Fri Feb 27 12:16:17 2015
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Enter user-name: / as sysdba
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> CREATE PUBLIC DATABASE LINK "DBPG_LNK" CONNECT TO "dblink_oracle" IDENTIFIED BY "dblink_oracle" USING 'DB_PGSQL';
Database link created.
SQL> SELECT DISTINCT "table_catalog", "table_schema" FROM "information_schema"."tables"@DBPG_LNK;
table_catalog table_schema
------------------- -------------------
: :
3. References
- http://alexsandrohaag.blogspot.com.br/2010/07/criando-um-database-link-entre-o-oracle.html
- https://dbaspot.wordpress.com/2013/05/29/how-to-access-postgresql-from-oracle-database/
- http://stackoverflow.com/questions/18998225/how-do-i-create-postgres-to-oracle-dblink
- http://vibhork.blogspot.com.br/2011/05/postgresql-database-link-to-oracle.html
- http://eduardolegatti.blogspot.com.br/2009/07/abordando-o-uso-de-database-links-em.html
- http://www.uptimemadeeasy.com/linux/install-postgresql-odbc-driver-on-linux/
- https://community.oracle.com/thread/2347870
- http://www.postseek.com/meta/4bae02f66a8c320be4d28e0d605bc05a
- http://cybergav.in/tag/isql-on-linux/
- http://stackoverflow.com/questions/6454146/getting-the-encoding-of-a-postgres-database-using-the-command-line
Este comentário foi removido pelo autor.
ResponderExcluirVery useful tutorial. Thank you very much.
ResponderExcluir1.) In a external connection escenario in order to avoid an "isql" error is required open Postgres database to external connections.
http://blog.bigbinary.com/2016/01/23/configure-postgresql-to-allow-remote-connection.html
2.) In our case we got the ora-28500 error when select through dblink. We resolved adding the following line on file initDB_PGSQL.ora
HS_LANGUAGE=AMERICAN_AMERICA.WE8ISO8859P1
Hello josemar, I followed your instructions and managed to access the PostgreSQL data, but I have an inconvenience with the accents and the letter ñ, I get some strange characters. Please your help on how I can solve this. Thank you
ResponderExcluirHi Hussein,
ResponderExcluirTry to go Back to step “Configure environment variables if necessary. In my case, I needed to force CHARSET ”.
Maybe you have Ro findo correct charset compatibility