yangtingkun
===========================================================
使用当前用户的数据库链的实现
===========================================================

今天在尝试使用当前用户的数据库链的时候发现了一个问题。


在建立一个数据库链的时候,由于不打算将密码输出到屏幕上,因此选择了使用不加CONNECT TO语句的数据库链,也就是说,数据库链会使用当前登陆数据库的用户和密码来尝试连接远端数据库。

这种情况要求当前的用户名和密码与远端数据库中的一致。由于当前用户是一致的,因此只需要通过SQLPLUSPASSWORD命令修改当前用户的密码,就可以保证远端数据库的用户密码和当前登陆用户密码一致,这样不需要将用户密码输出到屏幕,也不会以明文的方式保存到数据库中,还达到了访问远端对象的目的。

不过在操作当中发现了一个有趣的现象,下面通过一个例子来展示说明,不过为了大家可以看得更清楚,这里将PASSWORD命令替换为了ALTER USER IDENTIFIED BY语句:

SQL> CONN YANGTK/YANGTK@YTK92已连接。
SQL> CONN YANGTK/YANGTK@YTK102
已连接。
SQL> ALTER USER YANGTK IDENTIFIED BY TEST;

用户已更改。

SQL> CONN YANGTK/TEST@YTK102已连接。

首先更改YTK102数据库中的用户名密码,以便下面重现问题:

SQL> CREATE DATABASE LINK YTK92 USING 'YTK92';

数据库链接已创建。

SQL> SELECT * FROM GLOBAL_NAME@YTK92;
SELECT * FROM GLOBAL_NAME@YTK92
*
1 行出现错误:
ORA-01017: invalid username/password; logon denied
ORA-02063:
紧接着 line (起自 YTK92)


SQL> DROP DATABASE LINK YTK92;

数据库链接已删除。

SQL> ALTER USER YANGTK IDENTIFIED BY YANGTK;

用户已更改。

SQL> CREATE DATABASE LINK YTK92 USING 'YTK92';

数据库链接已创建。

SQL> SELECT * FROM GLOBAL_NAME@YTK92;
SELECT * FROM GLOBAL_NAME@YTK92
*
1 行出现错误:
ORA-01017: invalid username/password; logon denied
ORA-02063:
紧接着 line (起自 YTK92)

即使修改了当前用户的密码,使其与远端一致,数据库链仍然无法访问,报错不正确的用户名、密码。

只有使用新的密码重新登陆数据库,数据库链才能使用:

SQL> CONN YANGTK/YANGTK@YTK102已连接。
SQL> SELECT * FROM GLOBAL_NAME@YTK92;

GLOBAL_NAME
----------------------------------------
YTK92.YTK_THINKPAD

这个现象说明,Oracle在使用当前用户建立数据库链的时候,是通过用户登陆时输入的用户名、密码信息来建立信息的,而不是通过保存在数据库中的用户名、密码信息。登陆是输入的用户名和密码信息保存在当前会话的上下文中。如果用户改变了当前的用户的密码,这个时候只是数据库中保存的密码信息发生了变化,这并不会影响到当前这个已经存在的会话,而且,也不会影响内存中已经保存的用户名、密码信息。

Oracle建立数据库使用的用户名密码并不会由于当前用户修改了密码而有所改变,因此只用重新登陆,输入新的用户名、密码之后,当前用户的数据库链才能使用修改后的密码来建立连接。

这也说明了JOB方式为什么无法使用不带CONNECT TO语句的数据库链。由于JOB的启动不需要输入用户名、密码信息,因此自动运行的JOB就无法包含用户名、密码来建立数据库链连接。而如果用户手工执行JOB,当前会话中保存的用户名、密码就可以用来建立数据库链。

yangtingkun 发表于:2008.01.21 23:33 ::分类: ( ORACLE ) ::阅读:(6148次) :: 评论 (3)
re: 使用当前用户的数据库链的实现 [回复]

还真没有测试过。每次都是connect by 输入明文了。smile

jidongzheng 评论于: 2008.01.23 09:52
re: 使用当前用户的数据库链的实现 [回复]

我有一个过程,是通过数据库链连接其他多个数据库(其他服务器)统计数据的,再用job定时执行,但经常发生错误,几天就broken了,不知道怎么回事。
还有就是当执行数据库链到表的select时,select * from tab@link,怎么也要求提交commit呢?使用pl/sql developer,提交和回滚按钮可用。

liangzi 评论于: 2008.03.04 08:23
re: 使用当前用户的数据库链的实现 [回复]

发生错误的话,把错误信息抛异常出来,没有错误信息怎么定位问题。

根据Oracle的文档,A transaction begins with the first executable SQL statement.SELECT语句虽然不修改数据,但是也是事务的一部分。由于你访问远端对象,因此你已经开始了一个远端事务或者分布事务。所以这时可以进行提交和回滚。

其实本地执行完SELECT后也是开始了一个事务,只不过pl/sql developer工具认为这时没有必要提交或回滚而已。

yangtingkun 评论于: 2008.03.05 11:09

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...