今天在尝试使用当前用户的数据库链的时候发现了一个问题。
在建立一个数据库链的时候,由于不打算将密码输出到屏幕上,因此选择了使用不加CONNECT TO语句的数据库链,也就是说,数据库链会使用当前登陆数据库的用户和密码来尝试连接远端数据库。
这种情况要求当前的用户名和密码与远端数据库中的一致。由于当前用户是一致的,因此只需要通过SQLPLUS的PASSWORD命令修改当前用户的密码,就可以保证远端数据库的用户密码和当前登陆用户密码一致,这样不需要将用户密码输出到屏幕,也不会以明文的方式保存到数据库中,还达到了访问远端对象的目的。
不过在操作当中发现了一个有趣的现象,下面通过一个例子来展示说明,不过为了大家可以看得更清楚,这里将PASSWORD命令替换为了ALTER USER IDENTIFIED BY语句:
SQL> CONN YANGTK/YANGTK@YTK92
$h|\#a2m*_#]11906已连接。ITPUB个人空间
W6S6LH,| Pd)F
p#l
SQL> CONN YANGTK/YANGTK@YTK102ITPUB个人空间Y^1E6B_
已连接。
&_gN*z0v#{i11906SQL> ALTER USER YANGTK IDENTIFIED BY TEST;
用户已更改。
SQL> CONN YANGTK/TEST@YTK102
th3u6qWVK*?m11906已连接。
首先更改YTK102数据库中的用户名密码,以便下面重现问题:
SQL> CREATE DATABASE LINK YTK92 USING 'YTK92';
数据库链接已创建。
SQL> SELECT * FROM GLOBAL_NAME@YTK92;ITPUB个人空间/m"D+nz
Nc
SELECT * FROM GLOBAL_NAME@YTK92
(V`| Pz X;cO#[11906 *
y+ekSqH11906第1行出现错误:ITPUB个人空间$G.k@ Gr#D
ORA-01017: invalid username/password; logon denied
5moJ%\&o%z11906ORA-02063:紧接着line (起自YTK92)
!ffc/v0FoR-k
p2G11906SQL> DROP DATABASE LINK YTK92;
数据库链接已删除。
SQL> ALTER USER YANGTK IDENTIFIED BY YANGTK;
用户已更改。
SQL> CREATE DATABASE LINK YTK92 USING 'YTK92';
数据库链接已创建。
SQL> SELECT * FROM GLOBAL_NAME@YTK92;
n8zf z~$E11906SELECT * FROM GLOBAL_NAME@YTK92ITPUB个人空间X%mx5h9Fm3L
*ITPUB个人空间Pv5SV#|
第1行出现错误:
mD3J_?,_11906ORA-01017: invalid username/password; logon denied
fYjj If5g11906ORA-02063:紧接着line (起自YTK92)
即使修改了当前用户的密码,使其与远端一致,数据库链仍然无法访问,报错不正确的用户名、密码。
只有使用新的密码重新登陆数据库,数据库链才能使用:
SQL> CONN YANGTK/YANGTK@YTK102
^t!FeO-K11906已连接。ITPUB个人空间7X{8Ym0_
SQL> SELECT * FROM GLOBAL_NAME@YTK92;
GLOBAL_NAMEITPUB个人空间ge*I4{2E%Ah
----------------------------------------
c G/s9nC1}3c11906YTK92.YTK_THINKPAD
这个现象说明,Oracle在使用当前用户建立数据库链的时候,是通过用户登陆时输入的用户名、密码信息来建立信息的,而不是通过保存在数据库中的用户名、密码信息。登陆是输入的用户名和密码信息保存在当前会话的上下文中。如果用户改变了当前的用户的密码,这个时候只是数据库中保存的密码信息发生了变化,这并不会影响到当前这个已经存在的会话,而且,也不会影响内存中已经保存的用户名、密码信息。
而Oracle建立数据库使用的用户名密码并不会由于当前用户修改了密码而有所改变,因此只用重新登陆,输入新的用户名、密码之后,当前用户的数据库链才能使用修改后的密码来建立连接。
这也说明了JOB方式为什么无法使用不带CONNECT TO语句的数据库链。由于JOB的启动不需要输入用户名、密码信息,因此自动运行的JOB就无法包含用户名、密码来建立数据库链连接。而如果用户手工执行JOB,当前会话中保存的用户名、密码就可以用来建立数据库链。