用CREATE DATABASE LINK语句可以创建一个数据库连接。数据库连接是数据库中的一个schema实体,它可以允许你访问别的库的实体。其他数据库可以不一定要是数据库系统,然而访问non-Oracle系统你必须使用同质的服务。
在dblink创建完成后,你就可以在的SQL语句中通过在表、视图和PL/SQL实体的后面加@dblink对其进行访问了。你可以使用SELECT语句对远程数据库的实体进行访问,甚至可以使用INSERT UPDATE DELETE或者LOCK TABLE语句。
查看现有的数据库连接的视图有以下:
select * from v$dblink; select * from all_db_links; select * from dba_db_links; select * from user_db_links;
前提条件
创建私有数据库连接,你必须要有CREATE DATABASE LINK权限;创建公共数据库连接,你必须拥有CREATE PUBLIC DATABASE LINK权限;当然你还必须拥有远程数据库的CREATE SESSION权限;最后就是本地和远程数据库都安装了Oracle Net。
语法
SHARED
指定SHARED参数创建的数据库连接可以在被连接源数据库和目标数据库的单个网络中的多个会话共享。在一个共享服务器的配置中,共享的数据库连接可以防止连接远程数据库的链接数量变得太大。共享数据库链接可以是公共数据库链接。共享私有链接对多个客户端连接到同一个本地的schema有极大的用处。
PUBLIC
通过PUBLIC参数创建的数据库链接对所有用户都可见。如果你忽略这个参数,那么所创建的数据库链接是私有的,只对当前用户可用。能否访问远程数据库的数据取决于连接远程数据库时所使用的认证方式。
*如果你指定的是CONNECT TO user IDENTIFIED BY password,那么数据库连接时会使用指定的用户和密码。
*如果指定的是CONNECT TO CURRENT_USER,那么数据库起作用的的用户取决于所使用链接的作用范围。
*如果上面两种方式的参数都忽略了,那么数据库使用本地用户连接到远程数据库。
dblink
dblink用于指定完整或不完整的数据库连接名。如果你只指定了数据库名,那么Oracle数据库会隐式的追加本地数据库的域名。dblink只接受ASCII字符串,并且不支持多个字符串。数据库链接名不区分大小写,并且只以大写的ASCII字符存储。如果你在数据库名中使用了引号,那么引号将会被忽略。
如果GLOBAL_NAMES初始化参数被设置成TRUE,那么数据库连接必须使用与它所连接的库的名字;反之,如果是false,而你又改变了数据库的全局名,那么你可以使用这个改变后的全局名。
在一个会话或一个RAC实例配置中可以创建的数据库链接的最大个数,取决于OPEN_LINKS和OPEN_LINKS_PER_INSTANCE初始化参数的值。
创建数据库链接的局限
你不能为别的用户的schema创建数据库链接,也不可以一个schema的名字作为dblink的名字。点号允许出现在数据库链接中,因此Oracle数据库会对整个名字进行转换,例如ralph.linktosales(ralph是schema名,linktosales是链接名)。
CONNECT TO参数
CONNECT TO参数用于指定连接远程数据库的用户和凭证。
CURRENT_USER参数
CURRENT_USER参数用于创建一个当前用户数据库链接。CURRENT_USER必须是远程数据库中的合法全局用户。
如果数据库连接是直接被使用的,而不是从一个存储的对象实体中引用的,那么CURRENT_USER与链接的用户相同。
当执行一个存储的对象实体(存储过程、试图、触发器)来初始化一个数据库链接时,CURRENT_USER的名字与该存储对象的拥有者相同,而不是调用该存储对象的用户。例如,数据库链接在存储过程scott.p中(由scott创建),然后又用户jane调用该存储过程,那么CURRENT_USER是scott。
但是,如果存储实体是调用者权限的函数、存储过程或包,那么调用者的认证ID将会被用作连接的远程用户。例如,如果有权限限制的数据库链接包含在存储过程scott.p中(由scott创建的调用者权限的存储过程),一个名为Jane的用户调用了该存储过程,那么CURRENT_USER是jane,存储过程Jane的权限执行。
user IDENTIFIED BY password
用于指定连接远程数据库的用户名和密码,这个叫用户数据库链接。如果你忽略了这个参数,那么数据库会使用连接到数据库的用户的用户名和密码。这个叫连接用户数据库链接。
dblink_authentication
只有当你创建的是共享数据库链接时才能指定这个参数,也就是说你必须指定SHARED参数才能使用这个参数。这个参数可以指定用于连接到目标哭的用户名和密码。用户名必须是远程用户的合法用户并且密码是正确的。这个用户名和密码只当认证用,除此之外这个用户名和密码就没有别的其他操作了。
USING 'connect string'
用于指定远程数据库的服务名。如果你只给出了数据库名,那么Oracle数据库会隐式地在连接字符串中追加数据库的域名来创建一个完整的服务名。所以,如果远程数据库的数据库域名与当前库不同时,那么你必须制定一个完整的服务名。
例子
例子假设有两个数据库,分别是local和remote。这个例子中将会用Oracle数据库的域名,也就是所它们的域名将会不同。
1.定义一个公共数据库连接
下面定义一个名为remote的共享的公共数据库连接,并通过服务名remote来引用数据库。
CREATE PUBLIC DATABASE LINK remote USING 'remote';
local数据库的用户hr通过这个数据库链接来更新remote数据库的表(假设hr数据库有相应的权限):
UPDATE employees@remote SET salary=salary*1.1 WHERE last_name = 'Baer';
2.定义一个固定用户数据库链接
下面语句,remote数据库上的用户hr在local数据库的hr的schema定义了一个名为local固定的数据库链接。
CREATE DATABASE LINK local CONNECT TO hr IDENTIFIED BY password USING 'local';
当数据库链接创建后,hr用户可以通过以下方式查询local数据库hr schema中的表:
SELECT * FROM employees@local;
hr用户也可以通过DML语句修改local数据库中的数据:
INSERT INTO employees@local (employee_id, last_name, email, hire_date, job_id) VALUES (999, 'Claus', 'sclaus@example.com', SYSDATE, 'SH_CLERK'); UPDATE jobs@local SET min_salary = 3000 WHERE job_id = 'SH_CLERK'; DELETE FROM employees@local WHERE employee_id = 999;
通过这个固定数据库链接,remote数据库上的hr用户也可以访问同一个库中其他用户的表。这些语句假设hr用户有oe.customers表的read和select权限。这些语句链接到local数据库的hr用户并执行对oe.customers表的查询:
SELECT * FROM oe.customers@local;
3.定义一个CURRENT_USER的数据库链接
下面语句定义了一个到remote数据库的current-user数据库链接,并拿完整的服务名当作链接的名字。
CREATE DATABASE LINK remote.us.example.com CONNECT TO CURRENT_USER USING 'remote';
能执行上述语句的用户必须是一个在LDAP目录服务中注册的全局用户。
你可以创建一个同义词来将remote数据库上的表隐藏起来。
CREATE SYNONYM emp_table FOR oe.employees@remote.us.example.com;