11/06/2015 Oracle Database Links Survival Guide
Oracle Database Links Survival Guide
Martin Zahn, 06.02.2009
More Information can be found in the Oracle Distributed Database Management Guide
Overview
A database link is a schema object in one database that enables you to access objects on another
database. The other database need not be an Oracle Database system. However, to access non
Oracle systems you must use Oracle Heterogeneous Services.
Once you have created a database link, you can use it
to refer to tables and views on the other database. In
SQL statements, you can refer to a table or view on
the other database by appending @dblink to the table
or view name. You can query a table or view on the
other database with the SELECT statement. You can
also access remote tables and views using any
INSERT, UPDATE, DELETE, or LOCK TABLE statement.
Prerequisites
You must have the CREATE DATABASE LINK system privilege.
You must have the CREATE SESSION system privilege on the remote Oracle database.
You must be able to connect to the remote database.
Check GLOBAL_NAMES to setup the name of the database link.
DB_NAME
The DB_NAME parameter is the SID of the database and is the name used when creating the
database. It is specified within the [Link] parameter file or in the CREATE DATABASE command.
select name, value from v$parameter where name = 'db_name';
DB_DOMAN
The DB_DOMAIN parameter is the value of the domain to which the database belongs. It can be the
same as defined in the DNS and is usually the company name. However you can set a DB_DOMAIN
value which is not part of the DNS.
select name, value from v$parameter where name = 'db_domain';
GLOBAL_NAMES
GLOBAL_NAMES dictates how you might connect to a database. This variable is either TRUE or FALSE
and if it is set to TRUE it enforces database links to have the same name as the remote database to
[Link] 1/6
11/06/2015 Oracle Database Links Survival Guide
which they are connecting. Usually GLOBAL_NAMES is set to TRUE.
select name, value from v$parameter where name = 'global_names';
Setting the Name of the Database Link
You can query GLOBAL_NAME on the remote database to find out how the name of the database name
has to be on the local database.
CELLAR> sqlplus system/...@GENTIC
SQL> select global_name from global_name;
[Link]
So you have to set the database link name to [Link] if GLOBAL_NAMES is TRUE.
SQLNET
Setup your [Link] so you can connect to the remote database.
GENTIC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = [Link])(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = [Link])
)
)
CELLAR =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = [Link])(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = [Link])
)
)
Refer to Remote Table(s)
Suppose you want to refer to the table [Link] on GENTIC from CELLAR. On CELLAR the same
name [Link] should be used so you don't have to change any code.
sqlplus system/....@CELLAR
SQL> CREATE DATABASE LINK [Link]
CONNECT TO scott IDENTIFIED BY .....
USING 'GENTIC';
Database link created.
SQL> DESC [Link]@[Link];
Name Null? Type
LANGUAGE NOT NULL VARCHAR2(2)
ACTIVE NOT NULL NUMBER
TEXT VARCHAR2(20)
SQL> SELECT * FROM [Link]@[Link];
no rows selected
SQL> CREATE SYNONYM [Link] FOR [Link]@[Link];
Synonym created.
SQL> SELECT * FROM [Link];
no rows selected
SQL> INSERT INTO [Link](language, active, text) VALUES ('de',1,'german');
[Link] 2/6
11/06/2015 Oracle Database Links Survival Guide
SQL> INSERT INTO [Link](language, active, text) VALUES ('en',1,'english');
SQL> INSERT INTO [Link](language, active, text) VALUES ('fr',1,'french');
SQL> INSERT INTO [Link](language, active, text) VALUES ('it',1,'italian');
SQL> INSERT INTO [Link](language, active, text) VALUES ('ru',0,'russian');
SQL> COMMIT;
SQL> SELECT * FROM [Link];
LANGUA ACTIVE TEXT
de 1 german
en 1 english
fr 1 french
it 1 italian
ru 0 russian
As you can see, accessing the remote table is fully transparent to the application. Exactly
the same syntax can be used for the remote table if you create a synonym for the remote
table.
Executing Remote Procedures
You can also execute remote procedures ...
... here an example without synonym.
sqlplus system/....@CELLAR
SQL> DESC [Link]@[Link];
PROCEDURE aProcedure
Argument Name Type In/Out Default?
USER_ID NUMBER(10) IN
A_NAME VARCHAR2(32) IN
A_CONTENT VARCHAR2(4000) IN
A_DEFAULT NUMBER(1) IN
SQL> EXECUTE [Link]@[Link](1,'Test','Test',0);
PL/SQL procedure successfully completed.
And now the same with synonyms.
SQL> CREATE SYNONYM [Link] for [Link]@[Link];
Synonym created.
SQL> EXECUTE [Link](1,'Test','Test',0);
PL/SQL procedure successfully completed.
As you can see, executing remote procedures is fully transparent to the application.
Exactly the same syntax can be used for the remote package if you create a synonym for
the remote package.
[Link] 3/6
11/06/2015 Oracle Database Links Survival Guide
Distributed / InDoubt Transactions
A distributed transaction includes one or more statements that, individually or as a group, update
data on two or more distinct nodes of a distributed database.
The twophase commit mechanism ensures that all nodes either commit or perform a rollback
together. What happens if the transaction fails because of a system or network error? The transaction
becomes indoubt.
Distributed transactions can become indoubt in the following ways:
A server machine running Oracle software crashes.
A network connection between two or more Oracle databases involved in distributed processing
is disconnected.
An unhandled software error occurs.
The RECO process automatically resolves indoubt transactions when the machine, network, or
software problem is resolved. Until RECO can resolve the transaction, the data is locked for both
reads and writes. Oracle blocks reads because it cannot determine which version of the data to
display for a query.
Manually Committing an InDoubt Transaction
Suppose, the database server GENTIC crashes during a distributed transaction.
Prepare distributed transaction
SQL> CREATE SYNONYM [Link] FOR [Link]@[Link];
SQL> SELECT * from [Link];
SQL> CREATE TABLE [Link] (count NUMBER);
Start the distributed transaction
SQL> INSERT INTO [Link] (count) values (1);
SQL> INSERT INTO [Link] (count) values (2);
SQL> INSERT INTO [Link] (count) values (3);
SQL> INSERT INTO [Link] (count) values (4);
SQL> INSERT INTO [Link] (count) values (5);
SQL> INSERT INTO [Link](language, active, text) VALUES ('de',1,'german');
SQL> INSERT INTO [Link](language, active, text) VALUES ('en',1,'english');
SQL> INSERT INTO [Link](language, active, text) VALUES ('fr',1,'french');
SQL> INSERT INTO [Link](language, active, text) VALUES ('it',1,'italian');
SQL> INSERT INTO [Link](language, active, text) VALUES ('ru',0,'russian');
SQL> UPDATE [Link] SET count = 2 WHERE count = 1;
Now shutdown the distributed database
GENTIC> sqlplus / as sysdba;
shutdown abort;
Now try to COMMIT the distributed transaction
SQL> commit;
ERROR at line 1:
[Link] 4/6
11/06/2015 Oracle Database Links Survival Guide
ORA02054: transaction 1.37.5070 indoubt
ORA02068: following severe error from GENTIC
ORA03113: endoffile on communication channel
Now check the DBA_2PC_PENDING view for the LOCAL_TRAN_ID.
SET LINESIZE 500;
COL LOCAL_TRAN_ID FORMAT A13
COL GLOBAL_TRAN_ID FORMAT A50
COL STATE FORMAT A8
COL MIXED FORMAT A3
COL HOST FORMAT A10
COL COMMIT# FORMAT A10
SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, HOST, COMMIT#
FROM DBA_2PC_PENDING
/
LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE MIX HOST COMMIT#
1.37.5070 [Link].a05b1b48.1.37.5070 prepared no cellar 15508150
Now manually commit or rollback force the indoubt transaction as user SYS
SQL> exit;
sqlplus / as sysdba
SQL> COMMIT FORCE '1.37.5070';
Commit complete.
Manually remove an entry from the data dictionary
SQL> EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('1.37.5070');
PL/SQL procedure successfully completed.
More Information to Distributed Transactions can be found here
Database Link Types
When you create a database link, you must decide who will have access to it. The following sections
describe how to create the basic types of links.
Following are examples of private database links
SQL Statement Result
CREATE DATABASE LINK link_name; A private link using the global database name to the
remote database.
The link uses the userid/password of the connected
user. So if scott uses the link in a query, the link
establishes a connection to the remote database as
scott.
CREATE DATABASE LINK link_name A private fixed user link to the database with service
CONNECT TO user IDENTIFIED BY ... name service. The link connects to the remote
USING 'service'; database with the userid/password regardless of the
connected user.
CREATE DATABASE LINK link_name A private link to the database with service name
CONNECT TO CURRENT_USER USING service. The link uses the userid/password of the
'service'; current user to log onto the remote database.
Following are examples of public database links
sdasd
SQL Statement Result
CREATE PUBLIC DATABASE LINK A public link to the remote database. The link
link_name; uses the userid/password of the connected user.
So if scott uses the link in a query, the link
[Link] 5/6
11/06/2015 Oracle Database Links Survival Guide
establishes a connection to the remote database
as scott.
CREATE PUBLIC DATABASE LINK link_name A public link to the database with service name
CONNECT TO CURRENT_USER USING service. The link uses the userid/password of
'service'; the current user to log onto the remote
database.
CREATE PUBLIC DATABASE LINK link_name A public fixed user link. The link connects to the
CONNECT TO user IDENTIFIED BY ....; remote database with the userid/password.
[Link] 6/6